如何在生成和检查中应用xmodem CRC

时间:2018-07-06 03:55:01

标签: python crc crc16 xmodem

我已经重复了很多文章-由于某种原因,我找不到任何描述什么必须是简单过程的文章:如何将计算出的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”。我在这里想念东西吗?

2 个答案:

答案 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则为零。