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); }
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); } }