在对接腾讯云对象存储时,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 返回哈希值的大小(以位为单位)
}
					
 
			








