在对接腾讯云对象存储时,COS 会对新上传的对象进行 CRC64 校验,这就要求客户端程序具备计算文件 CRC64 校验值的能力。
根据腾讯云的文档,计算行为符合 ECMA-182 标准,经测试以下代码完全符合要求,且计算结果与腾讯云返回的结果一致。
public class CRC64ECMA182 { private const ulong Polynomial = 0xC96C5795D7870F42; // ECMA-182 多项式 private static readonly ulong[] _table; static CRC64ECMA182() { _table = new ulong[256]; for (ulong i = 0; i < 256; i++) { ulong crc = i; for (int j = 0; j < 8; j++) { crc = (crc & 1) == 1 ? (crc >> 1) ^ Polynomial : crc >> 1; } _table[i] = crc; } } // 计算给定文件的 CRC64 public static ulong ComputeCRC64(string filePath) { using (var fileStream = File.OpenRead(filePath)) { return ComputeCRC64(fileStream); } } // 计算给定流的 CRC64 public static ulong ComputeCRC64(Stream inputStream) { ulong crc = ulong.MaxValue; int bytesRead; var buffer = new byte[4096]; while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0) { for (int i = 0; i < bytesRead; i++) { crc = (crc >> 8) ^ _table[(crc & 0xFF) ^ buffer[i]]; } } return crc ^ ulong.MaxValue; } // 计算给定字节数组的 CRC64 public static ulong ComputeCRC64(byte[] data) { using (var memoryStream = new MemoryStream(data)) { return ComputeCRC64(memoryStream); } } }
此外,这里还有一个实现了 HashAlgorithm 的版本可供参考:
public class Crc64Ecma182 : HashAlgorithm { private const ulong Polynomial = 0xC96C5795D7870F42; // ECMA-182 polynomial private static readonly ulong[] _table; private ulong _crc; public Crc64Ecma182() { _crc = ulong.MaxValue; } static Crc64Ecma182() { _table = new ulong[256]; for (ulong i = 0; i < 256; i++) { ulong crc = i; for (int j = 0; j < 8; j++) { crc = (crc & 1) == 1 ? (crc >> 1) ^ Polynomial : crc >> 1; } _table[i] = crc; } } public override void Initialize() { _crc = ulong.MaxValue; } protected override void HashCore(byte[] array, int ibStart, int cbSize) { for (int i = ibStart; i < ibStart + cbSize; i++) { _crc = (_crc >> 8) ^ _table[(_crc & 0xFF) ^ array[i]]; } } protected override byte[] HashFinal() { ulong hashValue = _crc ^ ulong.MaxValue; return BitConverter.GetBytes(hashValue); } public override int HashSize => 64; // HashSize 返回哈希值的大小(以位为单位) }