使用 C# 开发程序对接腾讯云对象存储时,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 返回哈希值的大小(以位为单位)
}