private static void JenkinsLookup3Mix(ref uint a, ref uint b, ref uint c)
 {
     a -= c; a ^= ChecksumUtils.JenkinsLookup3Rot(c, 4);    c += b;
     b -= a; b ^= ChecksumUtils.JenkinsLookup3Rot(a, 6);    a += c;
     c -= b; c ^= ChecksumUtils.JenkinsLookup3Rot(b, 8);    b += a;
     a -= c; a ^= ChecksumUtils.JenkinsLookup3Rot(c, 16);   c += b;
     b -= a; b ^= ChecksumUtils.JenkinsLookup3Rot(a, 19);   a += c;
     c -= b; c ^= ChecksumUtils.JenkinsLookup3Rot(b, 4);    b += a;
 }
 private static void JenkinsLookup3Final(ref uint a, ref uint b, ref uint c)
 {
     c ^= b; c -= ChecksumUtils.JenkinsLookup3Rot(b, 14);
     a ^= c; a -= ChecksumUtils.JenkinsLookup3Rot(c, 11);
     b ^= a; b -= ChecksumUtils.JenkinsLookup3Rot(a, 25);
     c ^= b; c -= ChecksumUtils.JenkinsLookup3Rot(b, 16);
     a ^= c; a -= ChecksumUtils.JenkinsLookup3Rot(c, 4);
     b ^= a; b -= ChecksumUtils.JenkinsLookup3Rot(a, 14);
     c ^= b; c -= ChecksumUtils.JenkinsLookup3Rot(b, 24);
 }
示例#3
0
        private bool TryGetLinkMessageFromLinkInfoMessage(LinkInfoMessage linkInfoMessage,
                                                          string name,
                                                          [NotNullWhen(returnValue: true)] out LinkMessage?linkMessage)
        {
            linkMessage = null;

            var fractalHeap     = linkInfoMessage.FractalHeap;
            var btree2NameIndex = linkInfoMessage.BTree2NameIndex;
            var nameHash        = ChecksumUtils.JenkinsLookup3(name);
            var candidate       = default(LinkMessage);

            var success = btree2NameIndex.TryFindRecord(out var record, record =>
            {
                // H5Gbtree2.c (H5G__dense_btree2_name_compare, H5G__dense_fh_name_cmp)

                if (nameHash < record.NameHash)
                {
                    return(-1);
                }
                else if (nameHash > record.NameHash)
                {
                    return(1);
                }
                else
                {
#warning duplicate
                    using var localReader = new H5BinaryReader(new MemoryStream(record.HeapId));
                    var heapId            = FractalHeapId.Construct(this.Context, localReader, fractalHeap);
                    candidate             = heapId.Read(reader => new LinkMessage(reader, this.Context.Superblock));

                    // https://stackoverflow.com/questions/35257814/consistent-string-sorting-between-c-sharp-and-c
                    // https://stackoverflow.com/questions/492799/difference-between-invariantculture-and-ordinal-string-comparison
                    return(string.CompareOrdinal(name, candidate.LinkName));
                }
            });

            if (success)
            {
                if (candidate is null)
                {
                    throw new Exception("This should never happen. Just to satisfy the compiler.");
                }

                linkMessage = candidate;
                return(true);
            }

            return(false);
        }
        public static uint JenkinsLookup3(string key)
        {
            var bytes = Encoding.UTF8.GetBytes(key);

            return(ChecksumUtils.JenkinsLookup3Internal(bytes, 0));
        }
        /*
         * -------------------------------------------------------------------------------
         * H5_checksum_lookup3() -- hash a variable-length key into a 32-bit value
         * k       : the key (the unaligned variable-length array of bytes)
         * length  : the length of the key, counting by bytes
         * initval : can be any 4-byte value
         * Returns a 32-bit value.  Every bit of the key affects every bit of
         * the return value.  Two keys differing by one or two bits will have
         * totally different hash values.
         *
         * The best hash table sizes are powers of 2.  There is no need to do
         * mod a prime (mod is sooo slow!).  If you need less than 32 bits,
         * use a bitmask.  For example, if you need only 10 bits, do
         * h = (h & hashmask(10));
         * In which case, the hash table should have hashsize(10) elements.
         *
         * If you are hashing n strings (uint8_t **)k, do it like this:
         * for (i=0, h=0; i<n; ++i) h = H5_checksum_lookup( k[i], len[i], h);
         *
         * By Bob Jenkins, 2006.  [email protected].  You may use this
         * code any way you wish, private, educational, or commercial.  It's free.
         *
         * Use for hash table lookup, or anything where one collision in 2^^32 is
         * acceptable.  Do NOT use for cryptographic purposes.
         * -------------------------------------------------------------------------------
         */
        private static unsafe uint JenkinsLookup3Internal(byte[] bytes, uint initialValue)
        {
            uint a, b, c;

            /* Set up the internal state */
            var length = (uint)bytes.Length;

            a = b = c = 0xdeadbeef + length + initialValue;

            fixed(byte *p = bytes)
            {
                var k = p;

                /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
                while (length > 12)
                {
                    a += k[0];
                    a += ((uint)k[1]) << 8;
                    a += ((uint)k[2]) << 16;
                    a += ((uint)k[3]) << 24;
                    b += k[4];
                    b += ((uint)k[5]) << 8;
                    b += ((uint)k[6]) << 16;
                    b += ((uint)k[7]) << 24;
                    c += k[8];
                    c += ((uint)k[9]) << 8;
                    c += ((uint)k[10]) << 16;
                    c += ((uint)k[11]) << 24;
                    ChecksumUtils.JenkinsLookup3Mix(ref a, ref b, ref c);
                    length -= 12;
                    k      += 12;
                }

                /*-------------------------------- last block: affect all 32 bits of (c) */
                switch (length)                   /* all the case statements fall through */
                {
                case 12:    c += ((uint)k[11]) << 24;   goto case 11;

                case 11:    c += ((uint)k[10]) << 16;   goto case 10;

                case 10:    c += ((uint)k[9]) << 8;     goto case 9;

                case 9:     c += k[8];                  goto case 8;

                case 8:     b += ((uint)k[7]) << 24;    goto case 7;

                case 7:     b += ((uint)k[6]) << 16;    goto case 6;

                case 6:     b += ((uint)k[5]) << 8;     goto case 5;

                case 5:     b += k[4];                  goto case 4;

                case 4:     a += ((uint)k[3]) << 24;    goto case 3;

                case 3:     a += ((uint)k[2]) << 16;    goto case 2;

                case 2:     a += ((uint)k[1]) << 8;     goto case 1;

                case 1:     a += k[0];                  break;

                case 0:                                 return(c);

                default:
                    throw new Exception("This Should never be executed!");
                }

                ChecksumUtils.JenkinsLookup3Final(ref a, ref b, ref c);

                return(c);
            }
        }