C++中zlib的crc32和python zlib.crc32结果不一致的解决方案

背景

python和c++的代码中均有使用crc32分流的操作,需要保证分流得到的结果一致,那么两个crc32的方法得到的结果需要一致才行。然而实际测试中发现python2中zlib.crc32和c++的zlib中crc32得到的结果却不一致。

问题复现

python版crc32

import zlib
print zlib.crc32("helloworld")

结果为 -102031187。

如下:

C++ 版zlib crc32

#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动态链接库

赞赏

微信赞赏支付宝赞赏

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注