我尝试在go中计算m-bus消息的CRC16。
一个例子在第4页的以下文件中:http://fastforward.ag/downloads/docu/FAST_EnergyCam-Protocol-wirelessMBUS.pdf
10个数据字节和校验和(HEX):1244C418641610230102 B92F
Polynom是x^16+x^13+x^12+x^11+x^10+x^8+x^6+x^5+x^2+1
或0x3D65
不确定我做错了什么,但我绑了很多在线CRC计算器,没有人给我预期的校验和。我尝试用github.com/howeyc/crc16
来计算CRC16,但即使在这里我也会得到很多不同的值,具体取决于参数但从来没有正确的值。
我也有一些有相同问题的实时样本:2e44b05c12130000021b 8a66
,23446532710501883408 0607
我会采取任何有助于找到正确的crc的实现或实现。
感谢。
修改 好的,我明白了。我最终得到了两个函数来计算CRC:
func updateBitsReversed(crc uint16, tab *Table, p []byte) uint16 {
for _, v := range p {
crc = tab[byte(crc>>8)^v] ^ (crc << 8)
}
return crc
}
func update(crc uint16, tab *Table, p []byte) uint16 {
crc = ^crc
for _, v := range p {
crc = tab[byte(crc)^v] ^ (crc >> 8)
}
return ^crc
}
使用正确的表格updateBitsReversed
现在可以使用。
让我重新解释一下我的问题:在计算其余部分之前,我什么时候需要反转初始crc?这只是某些CRC定义的约定?
答案 0 :(得分:0)
提供一些背景信息:对于CRC16,您需要注意几个参数。有多项式和要使用的初始值(在大多数情况下为0x0000
或0xffff
)。同样,一个字节的位可以反映在输入上(这意味着位的顺序将被我们反转,该字节将被镜像)。
输出也可以反映出来,但是在这里您需要将计算值的16位反转。
最后一步是将结果与常数值进行异或运算(根据Wikipedia的说法,专有实现喜欢对任意值进行异或操作)。最后,您的求反是对最终XOR使用0xffff
的一种特殊情况。
对于wMBus,这些参数为:
polynomial: 0x3d65
initial: 0x0000
finalXOR: 0xffff
reflectIn: false
reflectOut: false
长话短说,在您的update()
函数返回时进行的最后一次反转可以解决问题,您的错误将在crc = ^crc
中。如果您将功能更改为此,它将起作用:
func update(crc uint16, tab *Table, p []byte) uint16 {
for _, v := range p {
crc = tab[byte(crc)^v] ^ (crc >> 8)
}
return ^crc
}
如果您需要更多信息,可以在sunshine2k.de上找到extensive explanation CRC;参数在第7章:CRC algorithm specification中进行了说明。