具有已知 CRC 的连接输入的 CRC

Jef*_*eff 2 crc32 crc

如果我有子串 S 0 , S 1 , ... S n与计算的 CRCs C 0 , C 1 , ... C n,我是否能够确定连接输入 S 0 S 1的 CRC C 0...n ...S n比线性处理整个字符串的效率要高得多?

显然, C 0...n = CRC(S 1...n,用 C 0初始化),但我想知道 C 0...n = f(C 0 ,C 1 ,... C n ) 用于某些具有 O(n) 复杂度的 f() 而不是 O(|S 0 S 1 ...S n |)。

Mar*_*ler 5

是的。您可以crc32_combine()zlib的实现中看到如何。它需要crc1crc2len2,其中len2crc2计算块中的字节数。它需要 O(log( len2)) 时间。可以对以下块重复组合。

该方法是继续对CRC计算crc1,用以下的len2零个字节,然后异或crc2。的len2字节施加具有零操作被重复平方并应用于每个1比特len2,这允许O(日志(len2))执行时间。该例程于 2004 年添加到 zlib。

  • 在按照您的建议使用预先计算的 poly^(2^n) 矩阵重写 `crc32_combine()` 后,我获得了大约 100 倍的加速,而且我确实看到在重复调用中对长度的约束越多,速度越快。对于 [8, 2048]B 中的长度(%8==0 -> avg 4b/8b set),每次使用 gcc 4.8/x86_64 和热缓存的 M*v 调用我得到大约 200-250 个周期,所以我认为可能如果我真的想发疯,还有进一步的手动调整空间。 (2认同)