首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C zlib crc32和Python crc32不匹配

C zlib crc32和Python crc32不匹配
EN

Stack Overflow用户
提问于 2015-01-20 07:30:53
回答 4查看 11.2K关注 0票数 2

我用Python和C语言做了一些crc32的实验,但是我的结果并不匹配。

代码语言:javascript
复制
C:
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>

#define NUM_BYTES 9

int
main(void)
{

  uint8_t bytes[NUM_BYTES] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

  uint32_t crc = crc32(0L, Z_NULL, 0);

  for (int i = 0; i < NUM_BYTES; ++i) {
    crc = crc32(crc, bytes, 1);
  }

  printf("CRC32 value is: %" PRIu32 "\n", crc);
}

给出输出CRC32 value is: 3136421207

Python

代码语言:javascript
复制
In [1]: import zlib
In [2]: int(zlib.crc32("123456789") + 2**32)
Out[2]: 3421780262

在python中,我将2**32添加到“强制转换”到未签名的int。

我在这里错过了什么?

编辑1

现在我试过了

代码语言:javascript
复制
In [8]: crc = 0;
In [9]: for i in xrange(1,10):
   ...:     crc = zlib.crc32(str(i), crc)
   ...:     
In [10]: crc
Out[10]: -873187034
In [11]: crc+2**32
Out[11]: 3421780262

代码语言:javascript
复制
int
main(void)
{

  uint32_t value = 123456789L;

  uint32_t crc = crc32(0L, Z_NULL, 0);

  crc = crc32(crc, &value, 4);

  printf("CRC32 value is: %" PRIu32 "\n", crc);
}

结果还是不一样。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-01-20 10:09:01

在原来的C和Python代码片段中存在问题。至于您的第二个C代码段,我没有尝试编译它,但是它是不可移植的,因为int中的字节顺序依赖于平台。因此,它将根据CPU的痴呆症给出不同的结果。

正如Serge所提到的,一个问题是{1, 2, 3, 4, 5, 6, 7, 8, 9}{'1', '2', '3', '4', '5', '6', '7', '8', '9'}之间的区别。另一个问题是,原始C代码中的循环实际上没有扫描数据,因为您在循环中没有使用i,就像bav提到的那样。

crctest.c

代码语言:javascript
复制
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>

#define NUM_BYTES 9

// gcc -std=c99 -lz -o crctest test.c

void do_crc(uint8_t *bytes)
{
    uint32_t crc = crc32(0L, Z_NULL, 0);

    for (int i = 0; i < NUM_BYTES; ++i)
    {
        crc = crc32(crc, bytes + i, 1);
    }

    printf("CRC32 value is: %lu\n", crc);
}

int main(void)
{
    uint8_t bytes0[NUM_BYTES] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    uint8_t bytes1[NUM_BYTES] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};

    do_crc(bytes0);
    do_crc(bytes1);
}

输出

代码语言:javascript
复制
CRC32 value is: 1089448862
CRC32 value is: 3421780262

crctest.py

代码语言:javascript
复制
#! /usr/bin/env python

import zlib

def do_crc(s):
    n = zlib.crc32(s)
    return n + (1<<32) if n < 0 else n

s = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09'
print `s`, do_crc(s)

s = b'123456789'
print `s`, do_crc(s)

输出

代码语言:javascript
复制
'\x01\x02\x03\x04\x05\x06\x07\x08\t' 1089448862
'123456789' 3421780262

编辑

下面是处理Python转换的更好方法:

代码语言:javascript
复制
def do_crc(s):
    n = zlib.crc32(s)
    return n & 0xffffffff

有关此主题的更多信息,请参见这里的答案:如何将python中的带符号整数转换为无符号整数

票数 5
EN

Stack Overflow用户

发布于 2015-01-20 09:10:56

根据对CRC计算和C例程有详细参考的www.lammertbies.nl,ASCII字符串1234567890xCBF43926中的CRC32,即以十进制形式表示的无符号32整数的3421780262

这意味着Python计算是正确的,但是要在C中获得相同的结果,您应该编写

代码语言:javascript
复制
uint8_t bytes[NUM_BYTES] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
uint32_t crc = crc32(0L, Z_NULL, 0);

或者,如果您想要的确实是用于uint8_t bytes[NUM_BYTES] = {1, 2, 3, 4, 5, 6, 7, 8, 9};的crc 32,则必须在python2.x中使用:

代码语言:javascript
复制
s = ''
for i in range(10):
    s += chr(i)
s

产出:'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t'

然后

代码语言:javascript
复制
zlib.crc32(s)

产出:1164760902

Nota:在python3.x中,您应该编写:s = bytes(range(10))

票数 2
EN

Stack Overflow用户

发布于 2015-01-20 08:57:52

您的第一个c-代码段的确切副本提供了相同的结果:

代码语言:javascript
复制
>>> bytes = [chr(i) for i in range(1, 10)]
>>> crc = zlib.crc32('', 0)
>>> for _ in range(9):
...     crc = zlib.crc32(bytes[0], crc)
>>> crc + 2**32
3136421207

注意,在循环中不使用i变量。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28039861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档