Created
June 1, 2016 09:15
-
-
Save pinscript/994f3533202cd70752c40d31b11f32a5 to your computer and use it in GitHub Desktop.
MurMurHash3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on https://gist.github.com/automatonic/3725443 | |
// with added Hash(string input) method and removed (int) cast to | |
// keep the hash unsigned. | |
public static class MurMurHash3 | |
{ | |
//Change to suit your needs | |
const uint seed = 144; | |
public static long Hash(string input) | |
{ | |
var buffer = Encoding.UTF8.GetBytes(input); | |
using (var ms = new MemoryStream(buffer)) | |
{ | |
return Hash(ms); | |
} | |
} | |
public static long Hash(Stream stream) | |
{ | |
const uint c1 = 0xcc9e2d51; | |
const uint c2 = 0x1b873593; | |
uint h1 = seed; | |
uint k1 = 0; | |
uint streamLength = 0; | |
using (BinaryReader reader = new BinaryReader(stream)) | |
{ | |
byte[] chunk = reader.ReadBytes(4); | |
while (chunk.Length > 0) | |
{ | |
streamLength += (uint)chunk.Length; | |
switch (chunk.Length) | |
{ | |
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; | |
} | |
chunk = reader.ReadBytes(4); | |
} | |
} | |
// finalization, magic chants to wrap it all up | |
h1 ^= streamLength; | |
h1 = fmix(h1); | |
unchecked //ignore overflow | |
{ | |
return 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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment