CRC64cs

Standard CRC 64

using System;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
public class CRC64 : HashAlgorithm
{
    /// <summary>
    ///     https://en.wikipedia.org/wiki/Polynomial_representations_of_cyclic_redundancy_checks
    /// </summary>
    public enum PolyType : ulong
    {
        ECMA182 = 0xD800000000000000,
        ISOPoly = 0xC96C5795D7870F42
    }
    private const  ulong   Seed = 0x0;
    private static ulong[] _table;
    private        ulong   _hash;
    public CRC64(PolyType pt = PolyType.ECMA182)
    {
        HashSizeValue = 64;
        InitializeTable((ulong) pt);
        Initialize();
    }
    public override void Initialize()
    {
        _hash = Seed;
    }
    protected override void HashCore(byte[] data, int start, int size)
    {
        State = 1;
        for (var i = start; i < start + size; i++)
            unchecked
            {
                _hash = (_hash >> 8) ^ _table[(data[i] ^ _hash) & 0xff];
            }
    }
    protected override byte[] HashFinal()
    {
        HashValue = UInt64ToBigEndianBytes(_hash);
        State     = 0;
        _hash     = Seed;
        return HashValue;
    }
    private static byte[] UInt64ToBigEndianBytes(ulong value)
    {
        var result = BitConverter.GetBytes(value);
        if (BitConverter.IsLittleEndian)
            Array.Reverse(result);
        return result;
    }
    public static string ToHex(byte[] data)
    {
        var builder = new StringBuilder();
        foreach (var item in data)
            builder.Append(item.ToString("X2", CultureInfo.InvariantCulture));
        return builder.ToString();
    }
    private static void InitializeTable(ulong polynomial)
    {
        _table = new ulong[256];
        for (var i = 0; i < 256; ++i)
        {
            var entry = (ulong) i;
            for (var j = 0; j < 8; ++j)
                if ((entry & 1) == 1)
                    entry = (entry >> 1) ^ polynomial;
                else
                    entry = entry >> 1;
            _table[i] = entry;
        }
    }
}