2018/05/23
Python2系とPython3系では binascii.crc32 の計算結果が異なるので注意
### python2 では signed、python3 では unsigned として扱われる 具体的な例としては以下。 ```python `title: "python2"; >>> import binascii >>> binascii.crc32(b"Hello") -137262718 ``` ```python `title: "python3"; >>> import binascii >>> binascii.crc32(b"Hello") 4157704578 ``` 数字は違うのですが、`0xF7D18982` を 32bit の signed として扱っているか、unsigned として扱っているかの違いです。 そして、これは仕様のようです。 > 参考 > > [Issue 4903: binascii.crc32() - document signed vs unsigned results - Python tracker](https://bugs.python.org/issue4903) ### 最上位ビットが 0 なら同じ つまり、最上位ビットが 0 になる場合は python2 でも python3 でも計算結果は同じになります。 ```python `title: "python2"; >>> import binascii >>> binascii.crc32(b"hello") 907060870 ``` ```python `title: "python3"; >>> import binascii >>> binascii.crc32(b"hello") 907060870 ``` ### 全部正の整数で取得したい場合 Python2 でも正の整数として取得したい場合は以下のようにします 。 ```python import binascii def calc_crc32(bytes): """ >>> calc_crc32(b"Hello") 4157704578 """ crc32 = binascii.crc32(bytes) return crc32 & 0xFFFFFFFF ``` ### 全部負の整数で取得したい場合 Python3 でも負の整数を出力したい場合は以下のようにします。 Python2 が混在する可能性がある場合、2系と3系で処理をわけないといけないので注意が必要です。 ```python import binascii import sys def calc_crc32(bytes): """ >>> calc_crc32(b"Hello") -137262718 """ crc32 = binascii.crc32(bytes) if sys.version_info[0] == 3: return crc32 - ((crc32 & 0x80000000) << 1) return crc32 ```
0 件のコメント:
コメントを投稿