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