如何计算无线M-Bus消息的CRC16

时间:2017-03-27 17:17:22

标签: crc16

我尝试在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+10x3D65

不确定我做错了什么,但我绑了很多在线CRC计算器,没有人给我预期的校验和。我尝试用github.com/howeyc/crc16来计算CRC16,但即使在这里我也会得到很多不同的值,具体取决于参数但从来没有正确的值。

我也有一些有相同问题的实时样本:2e44b05c12130000021b 8a6623446532710501883408 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定义的约定?

1 个答案:

答案 0 :(得分:0)

提供一些背景信息:对于CRC16,您需要注意几个参数。有多项式和要使用的初始值(在大多数情况下为0x00000xffff)。同样,一个字节的位可以反映在输入上(这意味着位的顺序将被我们反转,该字节将被镜像)。 输出也可以反映出来,但是在这里您需要将计算值的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中进行了说明。