Ejemplo n.º 1
0
        private string hashRelateBlankNode(string related, IDictionary <string, IDictionary <string, string> > quad, IdentifierIssuer issuer, string position)
        {
            /*
             * 1) Set the identifier to use for related, preferring first the
             * canonical identifier for related if issued, second the identifier
             * issued by issuer if issued, and last, if necessary, the result of
             * the Hash First Degree Quads algorithm, passing related.
             */
            string id;

            if (this.canonicalIssuer.hasID(related))
            {
                id = this.canonicalIssuer.getId(related);
            }
            else if (issuer.hasID(related))
            {
                id = issuer.getId(related);
            }
            else
            {
                id = hashFirstDegreeQuads(related);
            }

            /*
             * 2) Initialize a string input to the value of position.
             * Note: We use a hash object instead.
             */

            if (!position.Equals("g"))
            {
                return(NormalizeUtils.sha256Hash(Encoding.ASCII.GetBytes(position + getRelatedPredicate(quad) + id)));
            }
            else
            {
                return(NormalizeUtils.sha256Hash(Encoding.ASCII.GetBytes(position + id)));
            }
        }
Ejemplo n.º 2
0
        private IDictionary <string, Object> hashNDegreeQuads(IdentifierIssuer issuer, string id)
        {
            /*
             * 1) Create a hash to related blank nodes map for storing hashes that
             * identify related blank nodes.
             * Note: 2) and 3) handled within `createHashToRelated`
             */

            IDictionary <string, IList <string> > hashToRelated = this.createHashToRelated(issuer, id);

            /*
             * 4) Create an empty string, data to hash.
             * Note: We create a hash object instead.
             */

            string mdString = "";

            /*
             * 5) For each related hash to blank node list mapping in hash to
             * related blank nodes map, sorted lexicographically by related hash:
             */
            sortMapKeys(hashToRelated);
            foreach (var hash in hashToRelated.Keys)
            {
                var blankNodes = hashToRelated[hash];
                // 5.1) Append the related hash to the data to hash.
                mdString += hash;

                // 5.2) Create a string chosen path.

                string chosenPath = " ";

                // 5.3) Create an unset chosen issuer variable.

                IdentifierIssuer chosenIssuer = null;

                // 5.4) For each permutation of blank node list:

                string                    path           = "";
                List <string>             recursionList  = null;
                IdentifierIssuer          issuerCopy     = null;
                bool                      skipToNextPerm = false;
                NormalizeUtils.Permutator permutator     = new NormalizeUtils.Permutator(JArray.FromObject(blankNodes));

                while (permutator.HasNext())
                {
                    var permutation = permutator.Next();
                    // 5.4.1) Create a copy of issuer, issuer copy.

                    issuerCopy = (IdentifierIssuer)issuer.Clone();

                    // 5.4.2) Create a string path.

                    path = "";

                    /*
                     * 5.4.3) Create a recursion list, to store blank node
                     * identifiers that must be recursively processed by this
                     * algorithm.
                     */

                    recursionList = new List <string>();

                    // 5.4.4) For each related in permutation:
                    foreach (var related in permutation)
                    {
                        /*
                         * 5.4.4.1) If a canonical identifier has been issued for
                         * related, append it to path.
                         */

                        if (this.canonicalIssuer.hasID(related.ToString()))
                        {
                            path += this.canonicalIssuer.getId(related.ToString());
                        }
                        // 5.4.4.2) Otherwise:
                        else
                        {
                            /*
                             * 5.4.4.2.1) If issuer copy has not issued an
                             * identifier for related, append related to recursion
                             * list.
                             */

                            if (!issuerCopy.hasID(related.ToString()))
                            {
                                recursionList.Add(related.ToString());
                            }

                            /*
                             * 5.4.4.2.2) Use the Issue Identifier algorithm,
                             * passing issuer copy and related and append the result
                             * to path.
                             */

                            path += issuerCopy.getId(related.ToString());
                        }

                        /*
                         * 5.4.4.3) If chosen path is not empty and the length of
                         * path is greater than or equal to the length of chosen
                         * path and path is lexicographically greater than chosen
                         * path, then skip to the next permutation.
                         */

                        if (chosenPath.Length != 0 && path.Length >= chosenPath.Length && path.CompareTo(chosenPath) == 1)
                        {
                            skipToNextPerm = true;
                            break;
                        }
                    }
                }

                if (skipToNextPerm)
                {
                    continue;
                }

                // 5.4.5) For each related in recursion list:

                foreach (var related in recursionList)
                {
                    /*
                     * 5.4.5.1) Set result to the result of recursively
                     * executing the Hash N-Degree Quads algorithm, passing
                     * related for identifier and issuer copy for path
                     * identifier issuer.
                     */
                    IDictionary <string, object> result = hashNDegreeQuads(issuerCopy, related);

                    /*
                     * 5.4.5.2) Use the Issue Identifier algorithm, passing
                     * issuer copy and related and append the result to path.
                     */

                    path += "<" + (string)result["hash"] + ">";

                    /*
                     * 5.4.5.4) Set issuer copy to the identifier issuer in
                     * result.
                     */

                    issuerCopy = (IdentifierIssuer)result["issuer"];

                    /*
                     * 5.4.5.5) If chosen path is not empty and the length of
                     * path is greater than or equal to the length of chosen
                     * path and path is lexicographically greater than chosen
                     * path, then skip to the next permutation.
                     */

                    if (chosenPath.Length != 0 && path.Length >= chosenPath.Length && path.CompareTo(chosenPath) == 1)
                    {
                        skipToNextPerm = true;
                        break;
                    }
                }

                if (skipToNextPerm)
                {
                    continue;
                }

                /*
                 * 5.4.6) If chosen path is empty or path is lexicographically
                 * less than chosen path, set chosen path to path and chosen
                 * issuer to issuer copy.
                 */

                if (chosenPath.Length == 0 || path.CompareTo(chosenPath) == -1)
                {
                    chosenPath   = path;
                    chosenIssuer = issuerCopy;
                }

                // 5.5) Append chosen path to data to hash.
                mdString += chosenPath;

                // 5.6) Replace issuer, by reference, with chosen issuer.
                issuer = chosenIssuer;

                /*
                 * 6) Return issuer and the hash that results from passing data to hash
                 * through the hash algorithm.
                 */
            }

            /*
             * 6) Return issuer and the hash that results from passing data to hash
             * through the hash algorithm.
             */

            IDictionary <string, object> hashQuad = new Dictionary <string, object>();

            hashQuad.Add("hash", NormalizeUtils.sha256Hash(Encoding.ASCII.GetBytes(mdString)));
            hashQuad.Add("issuer", issuer);

            return(hashQuad);
        }
Ejemplo n.º 3
0
        /*
         * STATUS : working on it
         */
        private string hashFirstDegreeQuads(string id)
        {
            IDictionary <string, IList <Object> > info = this.blankNodeInfo[id];

            if (info.ContainsKey("hash"))
            {
                return(info["hash"].ToString());
            }

            // 1) Initialize nquads to an empty list. It will be used to store quads
            // in N-Quads format.
            IList <string> nquads = new List <string>();

            // 2) Get the list of quads quads associated with the reference blank
            // node identifier in the blank node to quads map.

            IList <Object> quads = info["quads"];

            // 3) For each quad quad in quads:
            foreach (var quad in quads)
            {
                // 3.1) Serialize the quad in N-Quads format with the following
                // special rule:

                // 3.1.1) If any component in quad is an blank node, then serialize
                // it using a special identifier as follows:

                // copy = {}

                IDictionary <string, IDictionary <string, string> > copy = new Dictionary <string, IDictionary <string, string> >();

                /* 3.1.2) If the blank node's existing blank node identifier
                 * matches the reference blank node identifier then use the
                 * blank node identifier _:a, otherwise, use the blank node
                 * identifier _:z.
                 * STATUS: working
                 */

                RDFDataset.Quad quadMap = (RDFDataset.Quad)quad;
                foreach (var key in quadMap)
                {
                    IDictionary <string, string> component = new Dictionary <string, string>();
                    component.Add(key.Key, key.Value.ToString());
                    if (key.Equals("predicate"))
                    {
                        copy.Add(key.Key, component);
                        continue;
                    }
                    copy.Add(key.Key, modifyFirstDegreeComponent(component, id));
                }

                RDFDataset.Quad copyQuad = new RDFDataset.Quad(copy, copy.ContainsKey("name") && copy["name"] != null
                    ? (copy["name"])["value"] : null);
                nquads.Add(RDFDatasetUtils.ToNQuad(copyQuad, copyQuad.ContainsKey("name") && copyQuad["name"] != null
                    ? (string)((IDictionary <string, object>)copyQuad["name"])["value"] : null));

                // 4) Sort nquads in lexicographical order.
            }

            Collections.SortInPlace(nquads);

            // 5) Return the hash that results from passing the sorted, joined
            // nquads through the hash algorithm.

            return(NormalizeUtils.sha256HashnQuads(nquads));
        }