CRC的计算过程你真的搞明白了吗??

在网上搜索CRC的相关资料,一下搜出一大堆,但是基本上都是讲的比较笼统,几乎都是千篇一律,但是按着网上搜的例程算了一遍自己要计算的数据,但是结果与用CRC软件算出来的结果不一致,是不是自己算错了呢?????

网上搜到的crc资料基本上都是用下面这个例子来解释CRC的,

但是我用在线的CRC工具输入上方数据是,产生的结果如下:

接下来就开始干货吧,直奔主题。

参数模型有以下较多的模型,共参考使用。

CRC算法参数模型解释: 
NAME:参数模型名称。 
WIDTH:宽度,即CRC比特数。 通常有8bit,16bit,24bit,32bit等。
POLY:生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。 
INIT:这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。 Init 的位数和Poly的位数相同,它的值为全0或者全F,当全为0时,在算法开始前对数据(这个数据是根据RefIn的值得到的)后面补上CRC位数个0后就可以进行后续计算了。当全为1时,表示在算法开始前对数据的前CRC位数(高位)先和对应位数个1进行异或(即:前CRC位数的值按位取反),再在后面补上CRC位数个0,才进行后续计算。

REFIN:待测数据的每个字节是否按位反转,True或False。 
REFOUT:在计算后之后,异或输出之前,整个数据是否按位反转,True或False。 

RefIn和Refout:它们要么全为False,要么全为True,

RefIn为False表示,输入的原始数据的每个字节的第7位作为最高有效位,第0为作为最低有效位,即正常计算即可。

当RefIn为True时,输入的原始数据的每个字节需要做个逆序的处理,注意:针对的每个字节,而不是整个数据,以一个4字节的原始数据为例:

当Refout为False时,输出不做处理,当Refout为True,需要对输出数据做一次整个数据的逆序处理,注意:这里做的逆序和RefIn不同,它不是按字节逆序,而是整个逆序,以CRC-32为例来说明,最后的数据为32位,当Refout为True时,翻转如下:

XOROUT:计算结果与此参数异或后得到最终的CRC值。

接下来举一个例子:

1) 0x13 对应二进制为00010011

2) 由于RefIn为True,所以0x13需要逆序一下得到11001000

3) 因为Init为0x00,所以2)的到11001000后面直接添加4个0即可,得到110010000000

4)  多项式为x4+x+1 对应二进制10011,将上述110010000000 除以10011

 整个计算过程如下:

     

最后得到余数:0010

7)由于RefOuT为True,所以余数要逆序变为0100

8)由于Xorout为0,表示不用再取反,所以最终的结果就是0100

接下来要计算一个16位的,有点挑战性的,看完后建议自己动手算一算,

要计算的数据为06050001FF00      理论上计算的CRC为4ddc。

先看看在线的crc计算结果

计算结果一致。

由于最近在用modbus通信用到了16位的CRC校验,所以做了一点点功课。

研究明白原理后自己也用手算了算,与上述计算结果一致。


————————————————
 

发布了138 篇原创文章 · 获赞 80 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/u012308586/article/details/105492084