You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/HashFunctions/Murmur3Unsafe.cs

100 lines
2.3 KiB

using System;
namespace ZeroLevel.Services.HashFunctions
{
public class Murmur3Unsafe
: IHash
{
private const uint Seed = 0xc58f1a7b;
private const UInt32 c1 = 0xcc9e2d51;
private const UInt32 c2 = 0x1b873593;
public unsafe UInt32 Hash(string s)
{
fixed (char* input = s)
{
return Hash((byte*)input, (uint)s.Length * sizeof(char), Seed);
}
}
public unsafe uint Hash(byte[] data)
{
fixed (byte* input = &data[0])
{
return Hash(input, (uint)data.Length, Seed);
}
}
public unsafe uint Hash(byte[] data, int offset, uint len, uint seed)
{
fixed (byte* input = &data[offset])
{
return Hash(input, len, seed);
}
}
private unsafe static uint Hash(byte* data, uint len, uint seed)
{
UInt32 nblocks = len / 4;
UInt32 h1 = seed;
//----------
// body
UInt32 k1;
UInt32* block = (UInt32*)data;
for (UInt32 i = nblocks; i > 0; --i, ++block)
{
k1 = *block;
k1 *= c1;
k1 = Rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = Rotl32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
//----------
// tail
k1 = 0;
uint rem = len & 3;
byte* tail = (byte*)block;
if (rem >= 3)
k1 ^= (uint)(tail[2] << 16);
if (rem >= 2)
k1 ^= (uint)(tail[1] << 8);
if (rem > 0)
{
k1 ^= tail[0];
k1 *= c1;
k1 = Rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
}
//----------
// finalization
h1 ^= len;
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 ^= h1 >> 16;
return h1;
}
private static UInt32 Rotl32(UInt32 x, int r)
{
return (x << r) | (x >> (32 - r));
}
}
}

Powered by TurnKey Linux.