- 数据字: 0100 1011 - 多项式: 1001 (x^3+1) - 因为最高指数x^3而填充3位 - 计算: 0100 1011 000 / 1001 -> 余数: 011
计算。
01001011000
1001
0000011000
1001
01010
1001
0011
编辑1:此前的评论/答案已由Mark Adler进行了验证。
Modbus RTU CRC16
当然,我很想知道不同版本的CRC是如何工作的,但我的主要兴趣是简单地了解在这里应用的机制。 到目前为止,我所知道的是:
- x16+x15+x2+1是多项式:0x18005或0b11000000000000101
- 初始值为0xFFFF
- 示例消息的十六进制:01 10 C0 03 00 01
- 上述消息的CRC16值的十六进制为:C9CD
我像上面的示例一样手动计算了这个值,但我宁愿不在这个问题中以二进制书写。 我认为我的二进制转换是正确的。 我不知道的是如何整合初始值 - 它是用于填充数据字中的还是零? 还是我需要将答案反转? 还是其他什么?
第一次尝试:用零填充16位。 计算出的二进制余数是
1111 1111 1001 1011
,这是十六进制中的FF9B
,对于CrC16/Modbus是不正确的,但对于CRC16/Bypass是正确的第二次尝试:由于初始值,用16位1填充。 计算出的二进制余数是
0000 0000 0110 0100
,这是十六进制中的0064
,不正确。
如果有人能解释或澄清我的假设就太好了。 老实说,我花了很多时间寻找答案,但每个解释都基于C/C++或其他语言的代码示例,而我不理解。 预先感谢您。
编辑1:根据此网站,“第一次尝试”指向具有相同多项式但不同初始值(0x0000)的另一种CRC16方法,这告诉我,计算应该是正确的。 我如何整合初始值?
编辑2:Mark Adlers答案解决了问题。 但是,现在我可以计算CRC16/Modbus,还有一些需要澄清的问题。 不需要但赞赏。
A)计算顺序将是:...?
- 应用RefIn完成完整输入(包括填充位)
- 在CRC16中,将InitValue与前16位
xor
- 应用RefOut完成完整输出/余数(在CRC16中的余数最多为16位)
B) 关于RefIn和RefOut: 无论我使用CRC8、CRC16还是CRC32,输入是否总是反射8位,输出是否总是反射所有位数?
C) 网站上的第3列(check)和第8列(XorOut)的含义是什么?后者似乎很容易理解,我猜测它被计算为在RefOut之后使用xor
的值,就像InitValue一样?
000
添加到消息01001011
的末尾。 - Mark Adler