Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
C# Murmur3 128bit Non Cryptographic Hashing Algorithm
public class Murmur3 : HashAlgorithm
{
private ulong _h1;
private ulong _h2;
private ulong _length;
public _result _res;
public Murmur3() : this(new _result { _h1 = 0, _h2 = 0 })
{
}
public Murmur3(_result seed)
{
Seed = seed;
Initialize();
}
public override int HashSize => 128;
public _result Seed { get; }
public new static Murmur3 Create()
{
return new Murmur3();
}
protected override void HashCore(byte[] array, int ibStart, int cbSize)
{
_length += (uint)cbSize;
unsafe
{
fixed (byte* pbyte = &array[ibStart])
{
var ppbyte = pbyte;
ulong k1;
ulong k2;
while (cbSize >= 16)
{
k1 = *(ulong*)ppbyte;
ppbyte += 8;
k2 = *(ulong*)ppbyte;
ppbyte += 8;
cbSize -= 16;
var O1 = k1 * 0x87c37b91114253d5ul;
_h1 = _h1 ^ (((O1 << 31) | (O1 >> 33)) * 0x4cf5ad432745937ful);
_h1 = (((_h1 << 27) | (_h1 >> 37)) + _h2) * 5 + 0x52dce729;
var O2 = k2 * 0x4cf5ad432745937ful;
_h2 = _h2 ^ (((O2 << 33) | (O2 >> 31)) * 0x87c37b91114253d5ul);
_h2 = (((_h2 << 31) | (_h2 >> 33)) + _h1) * 5 + 0x38495ab5;
}
k1 = 0;
k2 = 0;
switch (cbSize & 15)
{
case 15:
k2 ^= (ulong)*(ppbyte + 14) << 48;
goto case 14;
case 14:
k2 ^= (ulong)*(ppbyte + 13) << 40;
goto case 13;
case 13:
k2 ^= (ulong)*(ppbyte + 12) << 32;
goto case 12;
case 12:
k2 ^= (ulong)*(ppbyte + 11) << 24;
goto case 11;
case 11:
k2 ^= (ulong)*(ppbyte + 10) << 16;
goto case 10;
case 10:
k2 ^= (ulong)*(ppbyte + 9) << 8;
goto case 9;
case 9:
k2 ^= *(ppbyte + 8);
var O1 = k2 * 0x4cf5ad432745937ful;
_h2 ^= ((O1 << 33) | (O1 >> 31)) * 0x87c37b91114253d5ul;
goto case 8;
case 8:
k1 ^= (ulong)*(ppbyte + 7) << 56;
goto case 7;
case 7:
k1 ^= (ulong)*(ppbyte + 6) << 48;
goto case 6;
case 6:
k1 ^= (ulong)*(ppbyte + 5) << 40;
goto case 5;
case 5:
k1 ^= (ulong)*(ppbyte + 4) << 32;
goto case 4;
case 4:
k1 ^= (ulong)*(ppbyte + 3) << 24;
goto case 3;
case 3:
k1 ^= (ulong)*(ppbyte + 2) << 16;
goto case 2;
case 2:
k1 ^= (ulong)*(ppbyte + 1) << 8;
goto case 1;
case 1:
k1 ^= *ppbyte;
var O2 = k1 * 0x87c37b91114253d5ul;
_h1 ^= ((O2 << 31) | (O2 >> 33)) * 0x4cf5ad432745937ful;
break;
}
}
}
}
protected override unsafe byte[] HashFinal()
{
_h1 ^= _length;
_h2 ^= _length;
_h1 += _h2;
_h2 += _h1;
var V1 = _h1;
V1 = (V1 ^ (V1 >> 33)) * 0xFF51AFD7ED558CCDul;
V1 = (V1 ^ (V1 >> 33)) * 0xc4ceb9fe1a85ec53ul;
V1 ^= V1 >> 33;
_h1 = V1;
var V2 = _h2;
V2 = (V2 ^ (V2 >> 33)) * 0xFF51AFD7ED558CCDul;
V2 = (V2 ^ (V2 >> 33)) * 0xc4ceb9fe1a85ec53ul;
V2 ^= V2 >> 33;
_h2 = V2;
_h1 += _h2;
_h2 += _h1;
_res._h1 = _h1;
_res._h2 = _h2;
var fRes = new byte[16];
fixed (byte* pbyte = &fRes[0])
{
*(ulong*)pbyte = _h1;
}
fixed (byte* pbyte = &fRes[8])
{
*(ulong*)pbyte = _h2;
}
return fRes;
}
public override void Initialize()
{
_h1 = Seed._h1;
_h2 = Seed._h2;
_length = 0;
}
public struct _result
{
public ulong _h1;
public ulong _h2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment