// Copyright Keysight Technologies 2012-2019 // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, you can obtain one at http://mozilla.org/MPL/2.0/. /* This code is public domain. The MurmurHash3 algorithm was created by Austin Appleby and put into the public domain. See http://code.google.com/p/smhasher/ This C# variant was authored by Elliott B. Edwards and was placed into the public domain as a gist */ using System.IO; using System.Text; namespace Tap.Shared { internal static class MurMurHash3 { //Change to suit your needs const uint seed = 144; public static int Hash(byte[] bytes) { using (var stream = new MemoryStream(bytes)) return Hash(stream); } public static int Hash(string uniqueString) { byte[] input = Encoding.UTF8.GetBytes(uniqueString); using (var stream = new MemoryStream(input)) return Hash(stream); } public static int Hash(Stream stream) { const uint c1 = 0xcc9e2d51; const uint c2 = 0x1b873593; uint h1 = seed; uint k1 = 0; uint streamLength = 0; var reader = stream; byte[] chunk = new byte[4]; { while (true) { int len = reader.Read(chunk, 0, 4); if (len <= 0) break; streamLength += (uint)len; switch (len) { case 4: /* Get four bytes from the input into an uint */ k1 = (uint) (chunk[0] | chunk[1] << 8 | chunk[2] << 16 | chunk[3] << 24); /* bitmagic hash */ k1 *= c1; k1 = rotl32(k1, 15); k1 *= c2; h1 ^= k1; h1 = rotl32(h1, 13); h1 = h1 * 5 + 0xe6546b64; break; case 3: k1 = (uint) (chunk[0] | chunk[1] << 8 | chunk[2] << 16); k1 *= c1; k1 = rotl32(k1, 15); k1 *= c2; h1 ^= k1; break; case 2: k1 = (uint) (chunk[0] | chunk[1] << 8); k1 *= c1; k1 = rotl32(k1, 15); k1 *= c2; h1 ^= k1; break; case 1: k1 = (uint)(chunk[0]); k1 *= c1; k1 = rotl32(k1, 15); k1 *= c2; h1 ^= k1; break; } } } // finalization, magic chants to wrap it all up h1 ^= streamLength; h1 = fmix(h1); unchecked //ignore overflow { return (int)h1; } } private static uint rotl32(uint x, byte r) { return (x << r) | (x >> (32 - r)); } private static uint fmix(uint h) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; h ^= h >> 16; return h; } } }