FNV1a64.cs

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();
}
}
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(); } }
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();
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *