我需要将以下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 标准库中的一个,而不是移植自己的 CRC32 实现。由于历史原因,标准库包含两个相同的 CRC32 实现:
两种实现都与您的
crc32_1
函数的行为相匹配。要获得与问题中的 C 实现相匹配的结果,您只需应用常量偏移量。
请注意,
zlib
模块仅在CPython使用zlib支持编译时才可用(这几乎总是正确的)。如果您使用不带 zlib 的 CPythion 构建,您将无法使用 zlib
模块。相反,您可以使用 binascii
实现,该实现在可用时使用 zlib
,在不可用时默认为“内部”实现。