public static class MHRHash { private const uint m_seed = 0xffffffff; private const uint m_c1 = 0xcc9e2d51; private const uint m_c2 = 0x1b873593; private const uint m_c3 = 0xfaddaf14; private const int m_r1 = 15; private const int m_r2 = 13; public static int Hash(byte[] data) { if (data.Length % 4 != 0) throw new InvalidDataException($"{nameof(data)} is not 4 byte aligned."); int hashPosition = data.Length - 4; uint hash = m_seed; for (int i = 0; i < ((data.Length - 4) / 4); i++) { uint intData = BitConverter.ToUInt32(data, i * 4); uint eax = intData * m_c1; uint ecx; eax = rol32(eax, m_r1); ecx = eax * m_c2; hash ^= ecx; hash = rol32(hash, m_r2); hash += m_c3; long temp = hash + hash * 4; hash = (uint)temp; } byte twoBits = data[hashPosition]; uint extraHash = 0; if (twoBits == 3) { extraHash = (uint)data[hashPosition + 2] << 0x10; } if (twoBits == 2) { extraHash = (uint)data[hashPosition + 1] << 8; } if (twoBits == 1) { extraHash = data[hashPosition] ^ extraHash; extraHash *= m_c1; extraHash *= m_c2; hash ^= extraHash; } hash ^= (uint)hashPosition; hash ^= hash >> 16; hash *= 0x85ebca6b; hash ^= hash >> 13; hash *= 0xc2b2ae35; hash ^= hash >> 16; return (int)hash; } private static uint rol32(uint value, int amount) { return (value << amount) | (value >> (32 - amount)); } }