C# – CRC64

public class CRC64
{
    private readonly ulong[] _table;
    private readonly ulong _polynomial = 0x42F0E1EBA9EA3693;
    private readonly ulong _initialValue = 0x0000000000000000;
    private readonly ulong _finalXorValue = 0x0000000000000000;

    public CRC64()
    {
        _table = CreateLookupTable(_polynomial);
    }
    public CRC64(ulong polynomial, ulong initialValue, ulong finalXorValue)
    {
        _polynomial = polynomial;
        _initialValue = initialValue;
        _finalXorValue = finalXorValue;

        _table = CreateLookupTable(_polynomial);
    }

    public ulong Compute(byte[] bytes)
    {
        ulong current = _initialValue;
        for (var i = 0; i < bytes.Length; i++)
            current = TableValue(_table, bytes[i], current);

        return current ^ _finalXorValue;
    }

    private ulong PolynomialCaculate(int index, ulong polynomial)
    {
        ulong returnValue = (ulong)index;
        ulong topBit = (ulong)1L << (64 - 1);
        ulong mask = 0xffffffffffffffffUL;

        returnValue <<= (64 - 8);
        for (int i = 0; i < 8; i++)
        {
            if ((returnValue & topBit) != 0)
                returnValue = (returnValue << 1) ^ polynomial;
            else
                returnValue <<= 1;
        }
        return returnValue & mask;
    }

    private ulong[] CreateLookupTable(ulong polynomial)
    {
        ulong[] table = new ulong[256];
        for (var i = 0; i < 256; i++)
            table[i] = PolynomialCaculate(i, polynomial);

        return table;
    }

    private ulong TableValue(ulong[] table, byte b, ulong crc)
    {
        return table[((crc >> 56) ^ b) & 0xffUL] ^ (crc << 8);
    }
}

留言

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.