如何在替换少量字节时重新计算大字节数组上的CRC32

时间:2016-01-04 23:49:53

标签: c++ arrays crc

我有一个问题,即作为输入我有一个大字节数组(通常> 1K长度),它有一个计算的CRC32。我需要用不同的值替换一小部分数组,并重新计算CRC。有没有一种有效的方法可以在不循环整个原始字节数组的情况下执行此操作?我怀疑在数学上可以将原始CRC,要替换的字节,新字节作为输入,并使用一种算法来计算新CRC,该算法的循环大小只是要替换的字节数,但是& #39;在我的专业领域之外,因此,只是怀疑。谢谢,

2 个答案:

答案 0 :(得分:2)

是的,这可以做到。虽然在1K字节级别上,在整个事情上重新计算CRC很可能会更快。

如Dmitry Rubanovich所述,您可以使用CRC是线性函数的事实,其中加法被异或 - 替换。你可以做得更好,而不仅仅是避免重新计算到第一次更改。如果你有一个没有变化的长字符串,这是在两个消息的异或中的长字符串,你可以在O(log( n ))时间而不是O( n )时间。

这样做的方法是生成一系列32x32位矩阵,每个矩阵表示向CRC应用2个幂的零字节。例如。零字节,1,2,4,8等。这可以提前完成,生成静态表。然后,为了例如将CRC演变137个零,您将当前CRC乘以矩阵的128位,8位和1位的位向量。矩阵乘法超过GF(2),也就是说,加法被异或代替,并且乘法被和运算所取代。

您可以在zlib function for combining CRC's中看到如何完成此操作的示例。

使用指令计数进行快速计算表明,对于长度超过约300字节的零字符串,对数方法的平均速度会更快。

答案 1 :(得分:0)

CRC是线性的。所以CRC(A xor B)= CRC(A)xor CRC(B)。如果您确切知道要更改的位,则可以将位的更改分解为XOR运算。然后你只需要从B的最高有效位开始计算CRC。如果它接近流的末尾,将会有很多前导零。您不需要对它们运行CRC,因为0的CRC是0(crc是将多项式除以另一个多项式的余数...如果前导多项式系数为0,则可以忽略它们。)