python 中没有库的自定义 crc32 计算
custom crc32 calculation in python without libs
我一直在寻找可以生成 crc32 和的简单 python 代码。它适用于 stm32,我找不到一个很好的例子,它是 adjustable.
为了获得正确的计算设置,我使用了以下方面。
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
设置如下:
多项式:0x4C11DB7,
初始值:0xFFFFFFFF
并且没有异或值或 0x00,也没有反映输入和结果。
有人知道我在哪里可以获得简单的 adjustable 算法或者我可以在哪里学习如何编写一个算法吗?
编辑:
我使用这个函数来创建 table
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
有人可以帮助我吗?
首先,您拥有的是反射 CRC,而不是 non-reflected CRC。尽管您的 table 构造有误。这个:
if k & 1:
k ^= 0x4C11DB7
k >>= 1
错了。 exclusive-or 必须在轮班后完成。所以它需要是(对于反映的情况):
k = (k >> 1) ^ 0xedb88320 if k & 1 else k >> 1
请注意,在这种情况下也需要反映多项式。
代码中的另一个错误是使用 range
生成整数 0、1、...,并使用 those 而不是实际数据字节来计算CRC 上!你想要的 for 循环很简单:
for byte in bytestream:
使用 table 的全部意义在于使 CRC 计算更快。您不想每次执行 CRC 时都重新生成 table。您希望在程序启动时生成一次 table ,然后多次使用它。或者您可以从您的程序中单独生成 table,然后将 table 本身放入您的程序中。这就是通常所做的。
无论如何,要进行 非 反映的情况,您需要翻转一下。所以要使 table:
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
要使用 table:
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's CRC catalogue):
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()
例程中取出并在其他地方执行一次。
我一直在寻找可以生成 crc32 和的简单 python 代码。它适用于 stm32,我找不到一个很好的例子,它是 adjustable.
为了获得正确的计算设置,我使用了以下方面。
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
设置如下:
多项式:0x4C11DB7, 初始值:0xFFFFFFFF 并且没有异或值或 0x00,也没有反映输入和结果。
有人知道我在哪里可以获得简单的 adjustable 算法或者我可以在哪里学习如何编写一个算法吗?
编辑: 我使用这个函数来创建 table
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
有人可以帮助我吗?
首先,您拥有的是反射 CRC,而不是 non-reflected CRC。尽管您的 table 构造有误。这个:
if k & 1:
k ^= 0x4C11DB7
k >>= 1
错了。 exclusive-or 必须在轮班后完成。所以它需要是(对于反映的情况):
k = (k >> 1) ^ 0xedb88320 if k & 1 else k >> 1
请注意,在这种情况下也需要反映多项式。
代码中的另一个错误是使用 range
生成整数 0、1、...,并使用 those 而不是实际数据字节来计算CRC 上!你想要的 for 循环很简单:
for byte in bytestream:
使用 table 的全部意义在于使 CRC 计算更快。您不想每次执行 CRC 时都重新生成 table。您希望在程序启动时生成一次 table ,然后多次使用它。或者您可以从您的程序中单独生成 table,然后将 table 本身放入您的程序中。这就是通常所做的。
无论如何,要进行 非 反映的情况,您需要翻转一下。所以要使 table:
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
要使用 table:
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's CRC catalogue):
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()
例程中取出并在其他地方执行一次。