Fowler–Noll–Vo hash function 64-Bit
Updated: Jan-3,2021
using System; using System.Security.Cryptography; [Serializable] public class FNV1a64 : HashAlgorithm { private const ulong K = 0x100000001B3; private const ulong M = 0x1000000000000000; public ulong _hash; public ulong Hash; public ulong Seed = 0xCBF29CE484222325; public FNV1a64() { _hash = Seed; } public FNV1a64(ulong seed) { Seed = seed; _hash = Seed; } public override int HashSize => 64; public override void Initialize() { _hash = Seed; } protected override void HashCore(byte[] bytes, int ibStart, int cbSize) { Hash64(bytes, ibStart, cbSize); } private unsafe void Hash64(byte[] bytes, int ibStart, int cbSize) { if (bytes == null) return; if (ibStart >= bytes.Length || cbSize > bytes.Length) return; fixed (byte* pb = bytes) { var nb = pb + ibStart; while (cbSize >= 8) { _hash ^= *(ulong*) nb; nb += 8; cbSize -= 8; _hash *= K; _hash %= M; } switch (cbSize & 7) { case 7: _hash ^= *(ulong*) (nb + 6); _hash *= K; _hash %= M; goto case 6; case 6: _hash ^= *(ulong*) (nb + 5); _hash *= K; _hash %= M; goto case 5; case 5: _hash ^= *(ulong*) (nb + 4); _hash *= K; _hash %= M; goto case 4; case 4: _hash ^= *(ulong*) (nb + 3); _hash *= K; _hash %= M; goto case 3; case 3: _hash ^= *(ulong*) (nb + 2); _hash *= K; _hash %= M; goto case 2; case 2: _hash ^= *(ulong*) (nb + 1); _hash *= K; _hash %= M; goto case 1; case 1: _hash ^= *nb; _hash *= K; _hash %= M; break; } } } public unsafe ulong Hash64(byte[] bytes) { var cbSize = bytes.Length; _hash = Seed; fixed (byte* pb = bytes) { var nb = pb; while (cbSize >= 8) { _hash ^= *(ulong*) nb; nb += 8; cbSize -= 8; _hash *= K; _hash %= M; } switch (cbSize & 7) { case 7: _hash ^= *(ulong*) (nb + 6); _hash *= K; _hash %= M; goto case 6; case 6: _hash ^= *(ulong*) (nb + 5); _hash *= K; _hash %= M; goto case 5; case 5: _hash ^= *(ulong*) (nb + 4); _hash *= K; _hash %= M; goto case 4; case 4: _hash ^= *(ulong*) (nb + 3); _hash *= K; _hash %= M; goto case 3; case 3: _hash ^= *(ulong*) (nb + 2); _hash *= K; _hash %= M; goto case 2; case 2: _hash ^= *(ulong*) (nb + 1); _hash *= K; _hash %= M; goto case 1; case 1: _hash ^= *nb; _hash *= K; _hash %= M; break; } } return _hash; } protected override byte[] HashFinal() { Hash = _hash; return _hash.GetBytes(); } }