我已经重复了很多文章-由于某种原因,我找不到任何描述什么必须是简单过程的文章:如何将计算出的CRC与原始消息结合在一起,以便再次计算出CRC会得出0( =检查是否正确)?我确实找到了几个带有'longhand'计算(仅2或3位CRC)的示例,但没有找到使用诸如[crcmod][1]
之类的库函数(Python库)的示例。
这是我编写的一个简单程序,可以将其检出:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
import crcmod
def test_cycle():
test_str = b"123456789"
orig_msg = test_str
print("Original message: {:s}".format(orig_msg.hex()))
#~ crc_calc = crcmod.predefined.Crc('xmodem')
crc_calc = crcmod.Crc(
0x11021,
rev = False,
initCrc = 0x0000,
xorOut = 0x0000)
crc_calc.update(orig_msg)
print("CRC: {:04x}".format(crc_calc.crcValue))
lo = crc_calc.crcValue & 0xff
hi = crc_calc.crcValue >> 8
new_msg = test_str + bytes((hi, lo))
print("Crc appended: {:s}".format(new_msg.hex()))
crc_calc.update(new_msg)
print("CRC: {:04x}".format(crc_calc.crcValue))
def main(args):
test_cycle()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
有些注释行来自不同字节顺序的实验。该程序的结果是:
Original message: 313233343536373839
CRC: 31c3
Crc appended: 31323334353637383931c3
CRC: 00ef
第一个CRC(31C3
)似乎与the expected values for xmodem-CRC相对应。我尝试通过多种方式将获得的CRC与原始字符串组合在一起,但从未获得“ 0”。我在这里想念东西吗?
答案 0 :(得分:2)
crc_calc.update(new_msg)
将new_msg
的全部内容添加到CRC中。由于crc_calc
已经保存了313233343536373839
的结果,因此您可以有效地计算31323334353637383931323334353637383931c3
的CRC,而这确实是00ef
。
要仅将两个字节添加到计算中,请使用
crc_calc.update(bytes((hi, lo)))
或者,使用新的crcmod.Crc()
实例,或重置现有实例的crcValue
,然后再进行新的计算
crc_calc.crcValue = 0
crc_calc.update(new_msg)
两者都会给您0的结果
答案 1 :(得分:2)
提出此问题的人有一些背景,想知道是否添加CRC。
如果在消息中附加了正确的消息,而消息或CRC中没有引入错误,则整个事件的CRC将是恒定仅取决于该CRC的定义。
要正确地 附加CRC,需要注意比特顺序。对于crcmod
提供的通用CRC定义,如果rev
为假,则必须首先将 most 位附加到有效位之后。如果rev
为true,则必须首先在有效位后附加最低位。对于面向字节的消息,这首先意味着CRC的宽度必须是8位的倍数(顺便说一下,这是crcmod
允许的全部),并且CRC应该以big-endian附加。顺序或小端顺序。
根据CRC的定义,所得的常数并不总是为零。如果CRC的xorOut
值为零,则为 为零。否则,常数为 n 个零位的CRC,其中 n 是CRC的宽度,并且提供的初始CRC值为零(不是 initCrc
)。例如,对于标准CRC-32,消息的CRC-32附加了little-endian顺序,始终为0x2144df1c
。
对于这个特定问题,CRC以大端顺序附加,因此31 c3
,结果消息的CRC + CRC则为零。