【问题标题】:CRC of concatenated input with known CRCs [duplicate]具有已知 CRC 的级联输入的 CRC [重复]
【发布时间】:2014-05-27 17:05:30
【问题描述】:

如果我有子字符串 S0, S1, ... Sn 与计算的 CRC C0, C1, ... Cn, 我能确定串联输入 S0...n sub>0S1...Sn 比线性处理整个字符串的效率高得多?

显然,C0...n = CRC(S1...n, 用 C0 初始化),但我'想知道是否 C0...n = f(C0,C1,...Cn ) 用于复杂度为 O(n) 的 f() 而不是 O(|S0S1...Sn|)。

【问题讨论】:

  • @Oli Charlesworth 谢谢,sellibitze 提出的方法看起来很可行!回想起来,它的数学原理似乎很明显,但尾随零管理的技巧似乎启发了我。

标签: crc crc32


【解决方案1】:

是的。您可以在zlib 中查看crc32_combine() 的实现方式。它需要crc1crc2len2,其中len2 是计算crc2 的块中的字节数。它需要 O(log(len2)) 时间。可以为以下块重复组合。

方法是继续对crc1 进行CRC 计算,然后是len2 零字节,然后是异或crc2len2 字节与零运算符一起应用,该运算符重复平方并应用于len2 中的每个1 位,这允许 O(log(len2)) 执行时间。该例程于 2004 年被添加到 zlib。

【讨论】:

  • 正是我所寻找的,以及一个可靠的权威。谢谢!
  • 我刚刚对 crc32_combine() 进行了基准测试,并想知道在理论上是否可以进行任何大小/时间权衡优化以受益于较小的输入。 (交叉点与仅进行常规计算是 ~= 16b 随机长度/8 长度位设置)我正在考虑从级联压缩组件快速组装 gzip 流的可能性,并希望将组件组合成更接近 1kiB长度。
  • 是的。 crc32_combine() 每次调用时都会生成相同的运算符。您可以改为生成这些运算符并保​​存它们。如果你总是使用相同大小的块,比如长度n,你可以做得更好。您可以为 n 零创建单个运算符并将其应用到调用中,这将非常快。我在this answer 中有一个例子。
  • 哇,太好了。我刚刚打开 crc32.c 开始环顾四周,它看起来非常可行,尤其是其中的慷慨评论。非常感谢您的指导!
  • 按照您的建议,用预先计算的 poly^(2^n) 矩阵重写 crc32_combine() 后,我得到了大约 100 倍的加速,而且我确实看到在重复调用中限制长度越多,速度就会越快。对于 [8, 2048]B (%8==0 -> avg 4b/8b set) 中的长度,使用 gcc 4.8/x86_64 和热缓存的每个 M*v 调用我得到大约 200-250 个周期,所以我认为可能如果我真的想发疯的话,还有更多的手动调整空间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多