10

私は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 の計算は一致しますが、私の計算は一致しません。ネットで入手可能な例と比較したので、計算されたバイトの表は正しいと思います。したがって、問題は各バイトが計算されるルーチンである必要があります。誰かが私を正しい方向に向けることができますか?

前もって感謝します!

4

1 に答える 1

8

私はあなたのコードを詳しく見ていないので、エラーの正確な原因を特定することはできませんが、目的の出力を得るために簡単に微調整することができます:

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

微調整crc32binascii.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 バッファーを反転してから、最終的なバッファーの内容を反転することです。Soは0 ではなく にvalue初期化され、 を返す必要があります。これは と書くこともできます。つまり、結果の下位 32 ビットを反転して選択します。0xffffffffvalue ^ 0xffffffff~value & 0xffffffffvalue

于 2017-01-10T10:02:01.407 に答える