Fnv1a64Fast.cs

FNV1a 64Bit Hashing Fast

using System.Security.Cryptography;
/// <summary>
/// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
/// Very fast up to 2GBpS.
/// </summary>
public class Fnv1a64Fast : HashAlgorithm
{
private const ulong _prime = 0x100000001B3;
private readonly ulong _offset = 0xCBF29CE484222325;
private ulong _hash;
public ulong Hashf;
public Fnv1a64Fast()
{
_hash = _offset;
}
public Fnv1a64Fast(ulong seed)
{
_offset = seed;
_hash = _offset;
}
public override int HashSize => 64;
public override void Initialize()
{
_hash = _offset;
}
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;
unchecked
{
fixed (byte* pb = bytes)
{
var nb = pb + ibStart;
while (cbSize >= 8)
{
_hash ^= *(ulong*) nb;
_hash *= _prime;
nb += 8;
cbSize -= 8;
}
switch (cbSize & 7)
{
case 7:
_hash ^= *(ulong*) (nb + 6);
_hash *= _prime;
goto case 6;
case 6:
_hash ^= *(ulong*) (nb + 5);
_hash *= _prime;
goto case 5;
case 5:
_hash ^= *(ulong*) (nb + 4);
_hash *= _prime;
goto case 4;
case 4:
_hash ^= *(ulong*) (nb + 3);
_hash *= _prime;
goto case 3;
case 3:
_hash ^= *(ulong*) (nb + 2);
_hash *= _prime;
goto case 2;
case 2:
_hash ^= *(ulong*) (nb + 1);
_hash *= _prime;
goto case 1;
case 1:
_hash ^= *nb;
_hash *= _prime;
break;
}
}
}
_hash = _hash ^ (_hash >> 32);
Hashf = _hash;
}
protected override byte[] HashFinal()
{
var ba = new byte[8];
unsafe
{
fixed (byte* ptr = ba)
{
*(ulong*) ptr = _hash;
}
}
return ba;
}
}
using System.Security.Cryptography; /// <summary> /// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function /// Very fast up to 2GBpS. /// </summary> public class Fnv1a64Fast : HashAlgorithm { private const ulong _prime = 0x100000001B3; private readonly ulong _offset = 0xCBF29CE484222325; private ulong _hash; public ulong Hashf; public Fnv1a64Fast() { _hash = _offset; } public Fnv1a64Fast(ulong seed) { _offset = seed; _hash = _offset; } public override int HashSize => 64; public override void Initialize() { _hash = _offset; } 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; unchecked { fixed (byte* pb = bytes) { var nb = pb + ibStart; while (cbSize >= 8) { _hash ^= *(ulong*) nb; _hash *= _prime; nb += 8; cbSize -= 8; } switch (cbSize & 7) { case 7: _hash ^= *(ulong*) (nb + 6); _hash *= _prime; goto case 6; case 6: _hash ^= *(ulong*) (nb + 5); _hash *= _prime; goto case 5; case 5: _hash ^= *(ulong*) (nb + 4); _hash *= _prime; goto case 4; case 4: _hash ^= *(ulong*) (nb + 3); _hash *= _prime; goto case 3; case 3: _hash ^= *(ulong*) (nb + 2); _hash *= _prime; goto case 2; case 2: _hash ^= *(ulong*) (nb + 1); _hash *= _prime; goto case 1; case 1: _hash ^= *nb; _hash *= _prime; break; } } } _hash = _hash ^ (_hash >> 32); Hashf = _hash; } protected override byte[] HashFinal() { var ba = new byte[8]; unsafe { fixed (byte* ptr = ba) { *(ulong*) ptr = _hash; } } return ba; } }
using System.Security.Cryptography;
/// <summary>
///     https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
///     Very fast up to 2GBpS.
/// </summary>
public class Fnv1a64Fast : HashAlgorithm
{
    private const    ulong _prime  = 0x100000001B3;
    private readonly ulong _offset = 0xCBF29CE484222325;
    private          ulong _hash;
    public           ulong Hashf;
    public Fnv1a64Fast()
    {
        _hash = _offset;
    }
    public Fnv1a64Fast(ulong seed)
    {
        _offset = seed;
        _hash   = _offset;
    }
    public override int HashSize => 64;
    public override void Initialize()
    {
        _hash = _offset;
    }
    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;
        unchecked
        {
            fixed (byte* pb = bytes)
            {
                var nb = pb + ibStart;
                while (cbSize >= 8)
                {
                    _hash  ^= *(ulong*) nb;
                    _hash  *= _prime;
                    nb     += 8;
                    cbSize -= 8;
                }
                switch (cbSize & 7)
                {
                    case 7:
                        _hash ^= *(ulong*) (nb + 6);
                        _hash *= _prime;
                        goto case 6;
                    case 6:
                        _hash ^= *(ulong*) (nb + 5);
                        _hash *= _prime;
                        goto case 5;
                    case 5:
                        _hash ^= *(ulong*) (nb + 4);
                        _hash *= _prime;
                        goto case 4;
                    case 4:
                        _hash ^= *(ulong*) (nb + 3);
                        _hash *= _prime;
                        goto case 3;
                    case 3:
                        _hash ^= *(ulong*) (nb + 2);
                        _hash *= _prime;
                        goto case 2;
                    case 2:
                        _hash ^= *(ulong*) (nb + 1);
                        _hash *= _prime;
                        goto case 1;
                    case 1:
                        _hash ^= *nb;
                        _hash *= _prime;
                        break;
                }
            }
        }
        _hash = _hash ^ (_hash >> 32);
        Hashf = _hash;
    }
    protected override byte[] HashFinal()
    {
        var ba = new byte[8];
        unsafe
        {
            fixed (byte* ptr = ba)
            {
                *(ulong*) ptr = _hash;
            }
        }
        return ba;
    }
}