小编典典

Python CRC-32问题

python

我正在编写一个Python程序,以从6 GB
bz2文件的中间提取数据。bzip2文件由可独立解密的数据块组成,因此我只需要找到一个块(它们由魔术位分隔),然后从内存中从中创建一个临时的单块bzip2文件,最后将其传递给bz2.decompress函数。容易,不是吗?

bzip2格式的文件末尾具有crc32校验和。没问题,binascii.crc32即可解救。可是等等。要校验和的数据不一定在字节边界上结束,并且crc32函数在整数个字节上运行。

我的计划:在除最后一个字节以外的所有字节上使用binascii.crc32函数,然后使用我自己的函数以最后1–7位更新计算的crc。但是数小时的编码和测试使我感到困惑,而我的困惑可以归结为这个问题:crc32(“
\ x00”)不是0x00000000吗?根据Wikipedia的文章,不是吗?

您从0b00000000开始,并以32
0填充,然后使用0x04C11DB7进行多项式除法,直到前8位没有剩余(即刻)。您的最后32位是校验和,那怎么不能不全为零?

我已经在Google上搜索了答案,并查看了几种CRC-32实现的代码,却没有找到任何线索。


阅读 139

收藏
2020-12-20

共1个答案

小编典典

为什么crc32(“ \ x00”)不是0x00000000?

基本的CRC算法是将输入消息视为GF(2)中的多项式,除以固定的CRC多项式,然后将多项式余数用作结果哈希。

CRC-32对基本算法进行了许多修改:

  1. 消息的每个字节中的位都反转了。例如,字节0x01被视为多项式x ^ 7,而不是多项式x ^ 0。
  2. 该消息在右侧用32个零填充。
  3. 此反向填充消息的前4个字节与0xFFFFFFFF进行XOR。
  4. 其余多项式相反。
  5. 其余多项式与0xFFFFFFFF进行异或。
  6. 并回想一下,CRC-32多项式(非取反形式)为0x104C11DB7。

让我们算出一字节字符串0x00的CRC-32:

  1. 讯息:0x00
  2. 反转:0x00
  3. 填充:0x00 00 00 00 00
  4. 异或:0xFF FF FF FF 00
  5. 除以0x104C11DB7时的余数:0x4E 08 BF B4
  6. 异或:0xB1 F7 40 4B
  7. 反转:0xD2 02 EF 8D

有了它:0x00的CRC-32是0xD202EF8D。
(您应该对此进行验证。)

2020-12-20