背景
python和c++的代码中均有使用crc32分流的操作,需要保证分流得到的结果一致,那么两个crc32的方法得到的结果需要一致才行。然而实际测试中发现python2中zlib.crc32和c++的zlib中crc32得到的结果却不一致。
问题复现
python版crc32
import zlib print zlib.crc32("helloworld")
结果为 -102031187。
C++ 版zlib c++rc32
#include <zlib.h> #include <iostream> int main() { std::string str = "helloworld"; std::cout << crc32(0, reinterpret_cast<unsigned const char*>(&str[0]), str.size()) << std::endl; return 0;}
运行结果为:4192936109
python版得出的结果是-102031187,而C++版本得出的结果是4192936109。
资料查找
首先从百度上查看有没有人和我遇到同样的问题,结果发现有。但是回答的结果乱七八糟,没什么参考价值。
于是找了找python的文档,发现在python2中,crc32返回的是一个有符号的值,
Changed in version 2.6: The return value is in the range [-2**31, 2**31-1] regardless of platform. In older versions the value is signed on some platforms and unsigned on others.
Changed in version 3.0: The return value is unsigned and in the range [0, 2**32-1] regardless of platform.
解决方案
根据提示,可以发现对python中crc32得到的结果和0xffffffff按位相与就可以了。
>>> print zlib.crc32("helloworld") & 0xffffffff 4192936109
可以发现,结果和c++版本对上了。其他
python版本的crc32还有一个value参数,对应c++版本的的第一个参数
zlib.crc32(data[, value])
也就是说,如果改变value,计算出来的结果是不一样的。比如把value改为1,那么结果如下:
>>> print zlib.crc32("helloworld", 1) & 0xffffffff 371805075
这个时候就要求其他语言的版本的crc32有同样的初始值才能保证计算结果一致。
另外,使用zlib需要链接zlib动态链接库