是否可以在拆分中进行CRC-32计算?

我使用这个简单的函数来计算给定文件的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 > 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; 

我的问题是这样的:假设我有一个大文件,比如100MB。 在前50MB和最后50MB的CRC-32计算与100MB文件的CRC-32计算之间是否有任何关联?

我问的原因是,我有一些非常大的文件(约10GB给或拿)需要一些时间来生成,但是当它们被生成时,大多数部分保持静止,但是,部分在中间(已知点) )并且在开始时(标题,也称为部分/长度)。 计算10GB文件的CRC-32校验和需要相当长的时间,所以我想知道是否有任何方法可以在块中执行此操作?

确实可以并行化CRC-32计算,但细节很混乱,我需要花一天时间来提出代码。

让我们看一下基本的CRC算法,其中没有否定和没有位反转。

对于要计算CRC的字节串,我们将其称为消息。 基本思想是在GF(2)中将消息视为多项式,并计算其余数为CRC多项式的模数。

基本CRC算法是加性/线性的。 如果您有两条相同长度的消息a和b,则CRC(异或)(CRC)(CRC)exception(CRC)(b)。

此外,如果使用n个零填充右侧的消息,则新CRC将是CRC CRC次数x ^ n mod CRC多项式。

尽管如此,解决问题的唯一方法是真正理解CRC算法背后的数学并编写自己的自定义代码。 以下是对CRC的详尽解释: http ://www.ross.net/crc/download/crc_v3.txt

是。 有关crc32_combine()请参阅zlib中的crc32_combine()

这个等式是关键:

 CRC(a XOR b) == CRC(a) XOR CRC(b) 

假设您要计算以下消息的CRC:

 "Always desire to learn something useful." 

存在计算CRC的函数:

 crc_join(crc_part1("Always desire to lea"), crc_part2("rn something useful.")) 

如果crc_part1crc_part2为它们的参数填充( \0 ),则crc_join只是XOR。

 crc_part1 = crc("Always desire to lea\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") crc_part2 = crc("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0rn something useful.") 

可以使用查找表在crc_part1考虑尾随零。 crc_part2可以忽略前导零。

参考文献:

  1. 基于软件的CRC的高速并行架构
    Youngju。 做,Sung-Rok。 尹,Taekyu。 Kim,Kwang Eui。 Pyun和Sin-Chong。 公园
  2. https://en.wikipedia.org/wiki/Cyclic_redundancy_check

我知道这是一个老问题,但这是我用于“分块”CRC计算的,以防这有助于任何人:

 public static class Crc32Checksum { private static readonly uint[] Table = GenerateTable(); ///  /// Calculates a CRC32 value for the data given. ///  /// Data contents /// Byte offset to start reading /// Number of bytes to read /// The computed CRC32 value. public static int Calculate(byte[] data, int offset, int count) => Calculate(0, data, offset, count); ///  /// Calculates a new CRC32 value given additional data for the current CRC value. ///  /// The current CRC value to start with /// Additional data contents /// Byte offset to start reading /// Number of bytes to read /// The computed CRC32 value. public static int Calculate(int currentCrc, byte[] data, int offset, int count) { unchecked { uint crc = ~(uint)currentCrc; for (int i = offset, end = offset + count; i < end; i++) crc = (crc >> 8) ^ Table[(crc ^ data[i]) & 0xFF]; return (int)~crc; } } private static uint[] GenerateTable() { unchecked { var table = new uint[256]; const uint poly = 0xEDB88320; for (uint i = 0; i < table.Length; i++) { uint crc = i; for (int j = 8; j > 0; j--) { if ((crc & 1) == 1) crc = (crc >> 1) ^ poly; else crc >>= 1; } table[i] = crc; } return table; } } }