MurMurHashAlgorithm by John Gietzen

<PackageReference Include="MurMurHashAlgorithm" Version="1.0.2" />

 MurMurHash3Algorithm32x86

Computes the MurMurHash3 hash for the input data.
using System; using System.Security.Cryptography; namespace MurMurHashAlgorithm { public class MurMurHash3Algorithm32x86 : HashAlgorithm { private const uint C1 = 3432918353; private const uint C2 = 461845907; private const int ChunkSize = 4; private readonly uint seed; private uint h1; private uint length; private byte[] tail; private int tailLength; public override int HashSize => 4; public override int InputBlockSize => 4; public override int OutputBlockSize => 4; public MurMurHash3Algorithm32x86(int seed = 0) { this.seed = (uint)seed; Initialize(); } public override void Initialize() { h1 = seed; length = 0; tailLength = 0; } protected override void HashCore(byte[] array, int ibStart, int cbSize) { length += (uint)cbSize; if (tailLength > 0) { byte[] array2 = new byte[cbSize + tailLength]; Array.Copy(tail, array2, tailLength); Array.Copy(array, ibStart, array2, tailLength, cbSize); array = array2; ibStart = 0; cbSize = array2.Length; } int num = cbSize / 4; tailLength = cbSize % 4; if (tailLength != 0) { byte[] destinationArray = tail ?? (tail = new byte[3]); Array.Copy(array, ibStart + cbSize - tailLength, destinationArray, 0, tailLength); } for (int i = 0; i < num; i++) { uint block = GetBlock(array, ibStart, i); block = (uint)((int)block * -862048943); block = RotateLeft(block, 15); block *= 461845907; h1 ^= block; h1 = RotateLeft(h1, 13); h1 = (uint)((int)(h1 * 5) + -430675100); } } protected override byte[] HashFinal() { uint num = 0; switch (tailLength) { case 3: num = (uint)((int)num ^ (tail[2] << 16)); goto case 2; case 2: num = (uint)((int)num ^ (tail[1] << 8)); goto case 1; case 1: num ^= tail[0]; num = (uint)((int)num * -862048943); num = RotateLeft(num, 15); num *= 461845907; h1 ^= num; break; } h1 ^= length; FinalizationMix(ref h1); return BitConverter.GetBytes(h1); } private static void FinalizationMix(ref uint block) { block ^= block >> 16; block *= 2246822507; block ^= block >> 13; block *= 3266489909; block ^= block >> 16; } private static uint GetBlock(byte[] array, int start, int i) { i = start + i * 4; return (uint)(array[i++] | (array[i++] << 8) | (array[i++] << 16) | (array[i++] << 24)); } private static uint RotateLeft(uint x, byte r) { return (x << (int)r) | (x >> 64 - r); } } }