私はCRC32の計算に頭を悩ませようとしてきましたが、あまり成功していません。取得したように見える値が、取得すべき値と一致していません。
Pythonには、これらのチェックサムを生成できるライブラリ(つまり、zlibとbinascii)があることは知っていますが、CRC機能が存在しないため、それらを使用できるという贅沢はありません。 micropython。
これまでのところ、次のコードがあります。
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ビットを選択します。