从 C 到 Python 的 CRC 计算端口

问题描述 投票:0回答:1

我需要将以下CRC计算算法转换为Python:

#include <stdio.h>

unsigned int Crc32Table[256];

unsigned int crc32jam(const unsigned char *Block, unsigned int uSize)
{
    unsigned int x = -1; //initial value
    unsigned int c = 0;

    while (c < uSize)
    {
        x = ((x >> 8) ^ Crc32Table[((x ^ Block[c]) & 255)]);
        c++;
    }
    return x;
}

void crc32tab()
{
    unsigned int x, c, b;
    c = 0;

    while (c <= 255)
    {
        x = c;
        b = 0;
        while (b <= 7)
        {
            if ((x & 1) != 0)
                x = ((x >> 1) ^ 0xEDB88320); //polynomial
            else
                x = (x >> 1);
            b++;
        }
        Crc32Table[c] = x;
        c++;
    }
}

int main() {
    unsigned char buff[] = "whatever buffer content";
    unsigned int l = sizeof(buff) -1;
    unsigned int hash;

    crc32tab();
    hash = crc32jam(buff, l);
    printf("%d\n", hash);
}

两次(失败)尝试用 python 重写它:

def crc32_1(buf):
    crc = 0xffffffff
    for b in buf:
        crc ^= b
        for _ in range(8):
            crc = (crc >> 1) ^ 0xedb88320 if crc & 1 else crc >> 1
    return crc ^ 0xffffffff


def crc32_2(block):
    table = [0] * 256
    for c in range(256):
        x = c
        b = 0
        for _ in range(8):
            if x & 1:
                x = ((x >> 1) ^ 0xEDB88320)
            else:
                x >>= 1
        table[c] = x
    x = -1
    for c in block:
        x = ((x >> 8) ^ table[((x ^ c) & 255)])
    return x & 0xffffffff


data = b'whatever buffer content'

print(crc32_1(data), crc32_2(data))

对完全相同的数据使用三个例程会产生三个不同的结果:

mcon@cinderella:~/Desktop/3xDAsav/DDDAedit$ ./test5 
2022541416
mcon@cinderella:~/Desktop/3xDAsav/DDDAedit$ python3 test5.py 
2272425879 2096952735

如前所述:

C
代码是“黄金标准”,我如何在Python中解决这个问题?

注意:我知道我可以从 Python 调用

C
例程,但我认为这是“最后的手段”。

python c porting
1个回答
0
投票

您可以使用 Python 标准库中的一个,而不是移植自己的 CRC32 实现。由于历史原因,标准库包含两个相同的 CRC32 实现:

两种实现都与您的

crc32_1
函数的行为相匹配。要获得与问题中的 C 实现相匹配的结果,您只需应用常量偏移量

请注意,

zlib
模块仅在CPython使用zlib支持编译时才可用(这几乎总是正确的)。如果您使用不带 zlib 的 CPythion 构建,您将无法使用
zlib
模块。相反,您可以使用
binascii
实现,该实现在可用时使用 zlib
,在不可用时默认为“内部”实现。

© www.soinside.com 2019 - 2024. All rights reserved.