首页 > 解决方案 > 没有库的python中的自定义crc32计算

问题描述

我一直在寻找一个可以生成 crc32-sum 的简单 python 代码。它适用于 stm32,我找不到一个可调节的好例子。

为了让我的计算得到正确的设置,我使用了以下方面。

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

设置如下:

多项式:0x4C11DB7,初始值:0xFFFFFFFF 且无异或值或 0x00,也不反映输入和结果。

有人知道我在哪里可以获得一个简单的可调整算法,或者我可以在哪里学习如何编写一个?

编辑:我使用这个函数来创建表

def create_table():
    a = []
    for i in range(256):
        k = i
        for j in range(8):
            if k & 1:
                k ^= 0x4C11DB7
            k >>= 1
        a.append(k)
    return a

以及以下用于生成 crc-sum

def crc32(bytestream):
    crc_table = create_table()


    crc32 = 0xffffffff

    for byte in range( int(len(bytestream)) ):
        lookup_index = (crc32 ^ byte) & 0xff
        crc32 = (crc32 >> 8) ^ crc_table[lookup_index]

    return crc32

并用这个调用函数

print(hex(crc32(b"1205")))

结果是:0x9f8e7b8c

但网站给了我:0xA7D10A0A

有人能帮我吗?

标签: pythonpython-3.xstm32crc32

解决方案


首先,您所拥有的是反射 CRC,而不是非反射 CRC。尽管您的表格构造存在错误。这个:

if k & 1:
    k ^= 0x4C11DB7
k >>= 1

是错的。异或必须在班次之后完成。所以它需要(对于反映的情况):

k = (k >> 1) ^ 0xedb88320 if k & 1 else k >> 1

请注意,在这种情况下也需要反映多项式。

您的代码中的另一个错误是使用range整数 0、1、...,并使用这些而不是实际数据字节来计算 CRC!你想要的 for 循环很简单:

for byte in bytestream:

使用表格的全部意义在于使 CRC 计算更快。您不想每次执行 CRC 时都重新生成表。您希望在程序启动时生成一次表,然后多次使用它。或者您可以从您的程序中单独生成表格,然后将表格本身放入您的程序中。这就是通常所做的。

无论如何,要进行反射案例,您需要翻转事物。所以要制作表格:

def create_table():
    a = []
    for i in range(256):
        k = i << 24;
        for _ in range(8):
            k = (k << 1) ^ 0x4c11db7 if k & 0x80000000 else k << 1
        a.append(k & 0xffffffff)
    return a

要使用表格:

def crc32(bytestream):
    crc_table = create_table()
    crc = 0xffffffff
    for byte in bytestream:
        lookup_index = ((crc >> 24) ^ byte) & 0xff
        crc = ((crc & 0xffffff) << 8) ^ crc_table[lookup_index]
    return crc

现在它正确地实现了您的规范,恰好是 MPEG-2 32 位 CRC 规范(来自Greg Cook 的 CRC 目录):

width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000 check=0x0376e6e7 residue=0x00000000 name="CRC-32/MPEG-2"

对于上面的代码,如果我这样做:

print(hex(crc32(b'123456789')))

我得到0x376e6e7,它与目录中的检查值匹配。

同样,您需要create_table()摆脱crc32()常规并在其他地方做一次。


推荐阅读