绪论
在网上浏览了不少关于CRC校验的文章,基本上都是针对CRC校验原理的阐述以及关于CRC校验查表法的实际应用以及具体软件实现方法。
至于查的表是怎么来的,软件为何要这样实现不少文章并无说明。本篇文章就针对这两点问题进行总结和概括,有错误的地方欢迎你们评论区指出,不胜感激。
注意:本篇文章不涉及CRC校验的基本原理,若是不了解CRC的基本原理,请移步至以下连接:
CRC查找表法推导及代码实现比较
如下的CRC查表法的软件实现及推导过程均创建在modbusRTU协议使用的CRC-16标准。
html
查表法的表是怎么来的?
CRC16算法的生成多项式x 16 + x 15 + x 2 + 1 x^{16}+x^{15}+x^2+1x16+x15+x2+1,十六进制表示为0x8005。
CRC16常见的表格中的数据是按照先传输LSB,消息右移进寄存器来计算的。所以须要判断寄存器的最低位LSB,同时要将0x8005按位颠倒后(0xA001)根据LSB的状况决定是否与寄存器异或便可。
CRC16的表格中对应的数依次为0~255计算出来的CRC值,所以,此处只选取其中一两个数做为实例计算CRC值。
具体步骤以下所示:
1)从0~255中选取须要计算的数,将其对应的十六进制数放入一个长度为16的寄存器的低八位,高八位填充0;
2)若是寄存器的末位LSB为1,将寄存器的数值右移1位,再与0xA001位异或,不然仅将寄存器右移1位;
3)重复第2步,直到低八位所有右移出寄存器;
4)寄存器中的值则为校验码。
例如选择0x01做为计算CRC值:
算法
CRC-16的表格计算
举例:0x0001
多项式:0xA001
初始值:0x0000
如下为二进制显示
00000001 高八位填充0,与初始值异或 获得:
00000000 00000001 第一次
因为LSB=1 右移一位,高位添0
00000000 00000000 与0xA001异或 获得:
10100000 00000001第二次
因为LSB=1 右移一位,高位添0
01010000 00000000 与0xA001异或 获得:
11110000 00000001 第三次
因为LSB=1 右移一位,高位添0
01111000 00000000 与0xA001异或 获得:
11011000 00000001 第四次
因为LSB=1 右移一位,高位添0
01101100