如何用Python计算CRC32以匹配在线结果?

chr*_*kar 23 python crc32

我正在尝试使用Python计算/生成一些随机字符串的CRC32哈希值,但它们与我在线源生成的值不匹配.这是我在电脑上做的事情,

>>> import binascii
>>> binascii.crc32('hello-world')
-1311505829
Run Code Online (Sandbox Code Playgroud)

另一种方法,

>>> import zlib
>>> zlib.crc32('hello-world')
-1311505829
Run Code Online (Sandbox Code Playgroud)

上述结果相同的事实告诉我,我正在正确地调用该函数.但是,如果我转到以下在线资源,

对于字符串"hello-world",它们都给出相同的值= b1d4025b

有谁知道我需要做什么,以获得匹配的结果?

当我输入这个问题时,我想到我可能需要将我的Python结果转换为十六进制,

>>> hex(zlib.crc32('hello-world'))
'-0x4e2bfda5'
Run Code Online (Sandbox Code Playgroud)

不幸的是,这也没有帮助.:(

aba*_*ert 29

Python正在执行带符号的32位CRC.

那些站点正在进行无符号32位CRC.

否则,这些值是相同的,您可以从中看到:

>>> 0x100000000 - 0xb1d4025b == 0x4e2bfda5
True
Run Code Online (Sandbox Code Playgroud)

从32位有符号转换为32位无符号的快速方法是:*

>>> -1311505829 % (1<<32)
2983461467
Run Code Online (Sandbox Code Playgroud)

或者,以十六进制:

>>> hex(-1311505829 % (1<<32))
'0xb1d4025b'
Run Code Online (Sandbox Code Playgroud)

& 0xFFFFFFFF% 0x100000000& (2**32-1)% (2**32)等等都是等价的方式做同样的位变换; 它归结为哪一个你觉得最可读.


*这仅适用于执行整数除法的语言,如Python(-3 // 2 == -2); 在截断整数除法的语言中,如Java(-3 / 2 == -1),你仍然会得到一个负数.并且在那些甚至不需要除法和mod的语言中,如C一样,所有的赌注都是关闭的 - 但在C中,你只需将字节转换为你想要的类型......

  • “ Python正在执行带符号的32位CRC”。请注意:在Python3中,对它进行了更改,以使其运行无符号的CRC。请参阅[docs](https://docs.python.org/3/library/binascii.html#binascii.crc32)。 (2认同)
  • 这并不取决于除法是如何进行的,而是取决于“%”的定义。在大多数语言中,它被定义为以下之一:`x % y == x - Floor(x / y) * y`(“与除数相同的符号”,Python 的做法。非常积极,如 `2**32`是正数),`x % y == x - truncate(x / y) * y`(“与被除数符号相同”)或`x % y == x - round_towards_zero(x / y)`(“正模”) )。通常这与 / 相同,但并非总是如此。要在其他语言中始终进行正整数除法,您可以执行以下操作:“def Positive_mod(a, b): return ((a % b) + b) % b”。请参阅 https://en.wikipedia.org/wiki/Modulo_operation (2认同)

Ale*_*xey 15

zlib.crc32文档建议使用以下方法"在所有Python版本和平台上生成相同的数值".

import zlib
hex(zlib.crc32(b'hello-world') & 0xffffffff)
Run Code Online (Sandbox Code Playgroud)

结果0xb1d4025b如预期.

  • @chronodekar我在Python文档中没有找到任何明确的答案,所以我编辑了我的答案,以在所有Python版本和平台上具有相同的行为。 (2认同)

chw*_*w21 6

似乎python正在返回一个有符号整数(因此是负数),而其他人正在返回一个无符号整数。

我尝试使用 2^32 的模数,它给出了与这些站点相同的值。

>>> hex(zlib.crc32(b'hello-world')% 2**32)
'0xb1d4025b'
Run Code Online (Sandbox Code Playgroud)