我一直在尝试绕过CRC32计算而没有太大的成功,我似乎得到的值与我应该得到的值不匹配.
我知道Python有能够生成这些校验和的库(即zlib和binascii)但我没有能够使用它们的奢侈,因为在micropython上不存在CRC功能.
到目前为止,我有以下代码:
import binascii import zlib from array import array poly = 0xEDB88320 table = array('L') for byte in range(256): crc = 0 for bit in range(8): if (byte ^ crc) & 1: crc = (crc >> 1) ^ poly else: crc >>= 1 byte >>= 1 table.append(crc) def crc32(string): value = 0xffffffffL for ch in string: value = table[(ord(ch) ^ value) & 0x000000ffL] ^ (value >> 8) return value teststring = "test" print "binascii calc: 0x%08x" % (binascii.crc32(teststring) & 0xffffffff) print "zlib calc: 0x%08x" % (zlib.crc32(teststring) & 0xffffffff) print "my calc: 0x%08x" % (crc32(teststring))
然后我得到以下输出:
binascii calc: 0xd87f7e0c zlib calc: 0xd87f7e0c my calc: 0x2780810c
binascii和zlib计算同意我的那个没有.我相信计算出的字节表是正确的,因为我将它与网上可用的示例进行了比较.所以问题必须是计算每个字节的例程,有人能指出我正确的方向吗?
提前致谢!
我没有仔细查看您的代码,因此我无法确定错误的确切来源,但您可以轻松调整它以获得所需的输出:
import binascii from array import array poly = 0xEDB88320 table = array('L') for byte in range(256): crc = 0 for bit in range(8): if (byte ^ crc) & 1: crc = (crc >> 1) ^ poly else: crc >>= 1 byte >>= 1 table.append(crc) def crc32(string): value = 0xffffffffL for ch in string: value = table[(ord(ch) ^ value) & 0xff] ^ (value >> 8) return -1 - value # test data = ( '', 'test', 'hello world', '1234', 'A long string to test CRC32 functions', ) for s in data: print repr(s) a = binascii.crc32(s) print '%08x' % (a & 0xffffffffL) b = crc32(s) print '%08x' % (b & 0xffffffffL) print
产量
'' 00000000 00000000 'test' d87f7e0c d87f7e0c 'hello world' 0d4a1185 0d4a1185 '1234' 9be3e0a3 9be3e0a3 'A long string to test CRC32 functions' d2d10e28 d2d10e28
这里有几个测试,验证调整crc32
给出了相同的结果binascii.crc32
.
from random import seed, randrange print 'Single byte tests...', for i in range(256): s = chr(i) a = binascii.crc32(s) & 0xffffffffL b = crc32(s) & 0xffffffffL assert a == b, (repr(s), a, b) print('ok') seed(42) print 'Multi-byte tests...' for width in range(2, 20): print 'Width', width r = range(width) for n in range(1000): s = ''.join([chr(randrange(256)) for i in r]) a = binascii.crc32(s) & 0xffffffffL b = crc32(s) & 0xffffffffL assert a == b, (repr(s), a, b) print('ok')
产量
Single byte tests... ok Multi-byte tests... Width 2 Width 3 Width 4 Width 5 Width 6 Width 7 Width 8 Width 9 Width 10 Width 11 Width 12 Width 13 Width 14 Width 15 Width 16 Width 17 Width 18 Width 19 ok
正如评论中所讨论的,原始代码中的错误来源是该CRC-32算法反转初始crc缓冲区,然后反转最终缓冲区内容.因此value
初始化0xffffffff
为零而不是零,我们需要返回value ^ 0xffffffff
,也可以写入~value & 0xffffffff
,即反转value
,然后选择结果的低32位.