using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppLibs.Libs.Crypt
{
    public class CRC64
    {
        private const ulong Polynomial = 0xC96C5795D7870F42;
        private readonly ulong[] _table = new ulong[256];

        public CRC64()
        {
            for (ulong i = 0; i < 256; i++)
            {
                ulong crc = i;
                for (int j = 0; j < 8; j++)
                {
                    if ((crc & 1) == 1)
                    {
                        crc = (crc >> 1) ^ Polynomial;
                    }
                    else
                    {
                        crc >>= 1;
                    }
                }
                _table[i] = crc;
            }
        }

        public ulong ComputeHash(byte[] buffer)
        {
            ulong crc = 0xFFFFFFFFFFFFFFFF;
            foreach (byte b in buffer)
            {
                byte tableIndex = (byte)((crc ^ b) & 0xFF);
                crc = _table[tableIndex] ^ (crc >> 8);
            }
            return ~crc;
        }
        public string HashToString(byte[] data)
        {
            var hash = this.ComputeHash(data);
            return hash.ToString("X2");
        }
    }
}
