web-dev-qa-db-ja.com

Pythonとオンライン結果を一致させるためにCRC32を計算する方法は?

Python=を使用して、いくつかのランダムな文字列のCRC32ハッシュを計算/生成しようとしていますが、オンラインソースから生成した値と一致しません。

>>> import binascii
>>> binascii.crc32('hello-world')
-1311505829

別のアプローチ、

>>> import zlib
>>> zlib.crc32('hello-world')
-1311505829

上記の結果が同じであるという事実は、関数を正しく呼び出していることを示しています。ただし、次のオンラインソースにアクセスすると、

文字列「hello-world」の場合、すべて同じ値= b1d4025bが得られます

誰かが一致する結果を得るために私が何をする必要があるか知っていますか?

この質問を入力していたときに、Python結果を16進数に変換する必要があるかもしれない、

>>> hex(zlib.crc32('hello-world'))
'-0x4e2bfda5'

残念ながら、それも助けにはなりませんでした。 :(

19
chronodekar

Python 2は(py3とは異なり)署名された32ビットCRCを実行しています。

これらのサイトは、未署名の32ビットCRCを実行しています。

以下からわかるように、値は同じです。

_>>> 0x100000000 - 0xb1d4025b == 0x4e2bfda5
True
_

32ビット符号付きから32ビット符号なしに変換する簡単な方法の1つは次のとおりです。*

_>>> -1311505829 % (1<<32)
2983461467
_

または、16進数で:

_>>> hex(-1311505829 % (1<<32))
'0xb1d4025b'
_

_& 0xFFFFFFFF_または_% 0x100000000_または& (2**32-1)または% (2**32)などは、すべて同じビット調整を行う同等の方法です。もっとも読みやすいと思うものになります。


*これは、Python(_-3 // 2 == -2_);のようなフロア整数除算を行う言語でのみ機能します。 Java(_-3 / 2 == -1_)のような切り捨てられた整数の除算を行う言語では、依然として負の数になります。そして、Cのように除算とMODが適切に連携することさえ必要としない言語では、すべての賭けはオフになりますが、Cでは、バイトを必要なタイプにキャストするだけです...

27
abarnert

zlib.crc32 documentation は、「Pythonバージョンとプラットフォーム全体で同じ数値を生成する」ために、次のアプローチを使用することを提案しています。

import zlib
hex(zlib.crc32(b'hello-world') & 0xffffffff)

結果は0xb1d4025b 予想通り。

15
Alexey

pythonは負の数であるため符号付き整数を返しますが、他は符号なし整数を返します。

2 ^ 32のモジュラスを使用してみましたが、これらのサイトと同じ値が得られました。

>>> hex(zlib.crc32(b'hello-world')% 2**32)
'0xb1d4025b'
4
chw21