我使用这个简单的函数来计算给定文件的CRC校验和:
long i, j = 0;
int k = 0;
uint crc = 0xFFFFFFFF;
FileInfo file_info = new FileInfo(file);
byte[] file_buffer = new byte[32768];
FileStream file_stream = new FileStream(@file, FileMode.Open);
while ((i = file_stream.Read(file_buffer, 0, file_buffer.Count())) > 0)
{
for (j = 0; j < i; j++)
{
uint before = crc;
k = (int)((crc ^ file_buffer[j]) & 0x000000FFL);
uint after = (uint)((crc >> 8) & 0x00FFFFFFL) ^ crc32_table[k];
crc = after;
uint test = (uint)((crc << 8) & 0x00FFFFFFL) ^ crc32_table[k];
MessageBox.Show((~crc).ToString("X"));
}
}
file_stream.Close();
return ~crc;
Run Code Online (Sandbox Code Playgroud)
我的问题是这样的:假设我有一个大文件,比如100MB.前50MB和最后50MB的CRC-32计算和100MB文件的CRC-32计算之间是否有任何关联?
我问的原因是,我有一些非常大的文件(约10GB给或拿)需要一些时间来生成,但是当它们被生成时,大多数部分保持静止,但是,部分在中间(已知点) )并且在开始时(标题,也称为部分/长度).计算10GB文件的CRC-32校验和需要相当长的时间,所以我想知道是否有任何方法可以在块中执行此操作?
确实可以并行化 CRC-32 计算,但细节很混乱,我需要花大约一天的时间才能写出代码。
让我们看一下基本的 CRC 算法,其中没有求反,也没有位反转。
对于要计算 CRC 的字节串,我们将其称为消息。基本思想是,将消息视为GF(2)中的多项式,并计算其对 CRC 多项式取模的余数。
基本 CRC 算法是加法/线性的。如果有两条长度相同的消息 a 和 b,则 CRC(a XOR b) = CRC(a) XOR CRC(b)。
此外,如果在消息右侧填充 n 个零,则新的 CRC 将是旧的 CRC 乘以 x^n mod CRC 多项式。
话虽如此,解决问题的唯一方法是真正理解 CRC 算法背后的数学原理并编写自己的自定义代码。这是 CRC 的一个很长但非常完整的解释:http://www.ross.net/crc/download/crc_v3.txt