CRC
循环冗余码(Cyclic Redundancy Code, CRC)是一种用于校验通信链路上数字传输准确性的计算方法(通过某种数学运算来建立数据位和校验位(CRC)的约定关系的)。它是利用除法以及余数的原理来作错误侦测。
发送方: 使用某公式计算出被传送数据所含信息的一个值,并将此值 附在被传送数据后。
接收方: 对同一数据进行相同的计算,应该得到相同的结果。对比CRC结果。
数学背景
模二运算
模二运算,是一种二进制的四则运算,包括模二加(+)、模二减(-)、模二乘(x)、模二除(/) 四种二进制运算。与四则运算不同的是模二运算不考虑进位和借位.
重点
- 模二加法和模二减法的结果是相同的,并且与异或(XOR)运算的结果是一致的。 异或运算可以代替模二加减运算。可用硬件XOR异或门硬件代替运算。
- 模二乘法可看作两个步骤, 可用AND与门代替运算。
a. 第一步被乘数的位跟乘数进行与运算,再根据被乘数的阶进行左移被乘数的阶数位,被乘数的位数对应n个部分积。
b. 部分积进行模二加法运算。 - 模二乘除法与普通乘除法一样演算,区别是模二除法的被除数部分的阶数与除数P的阶数相同时,进行部分XOR异或运算,得到商数和余数,将余数的阶数与除数P循环计算,直到余数的阶数小于R,这个余数就是附加的校验码。
关注模二除法,因为它与CRC算法密切相关,它有三个性质: - 当最后余数的位数小于除数位数时,除法停止。
- 当被除数的位数小于除数位数时,则商数为0,被除数就是余数。
- 只要被除数或部分余数的位数与除数一样多,且最高位为1,不管其他位是什么数,皆可商1。
二进制多项式
对任意的二进制数都构造与其对应的一个二进制系数多项式。
例如:10011B,其对应的二进制系数多项式为P(X) = X^4 +X +1。
CRC算法中,对于二进制数都是以二进制系数多项式去描述的,。
CRC算法
CRC 算法的基本思想是将要传输数据后面填充N个0(既是传输数据信息左移N位)当做一个包含数据的多项式。将左移后的数据多项式 模二除以另一个生成多项式(Poly),得到的余数作为(CRC)校验数据附加到原数据后面。(模二除,CRC取余)
g(x)为校验码的生成多项式(上文中,除数的二级制多项式poly),不同的位数的CRC多项式,对应生成多项式的次幂不同,其纠错能力也不同。常见的标准多项式如下。
CRC-8算法为例,该算法生成多项式G(X)为
.除数p(x)为0b10000 0111。
CRC算法参数模型
NAME:参数模型名称,决定了CRC位宽和POLY生成多项式。
WIDTH:宽度,即CRC位数。
POLY:生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。
INIT:这是计算CRC循环冗余码时,在数据后面预填充的预置值,十六进制表示。
REFIN:控制输入数据是否进行反转操作,True或False。若False,则输入数据的比特顺序反转,通常是将最高有效位(MSB)变为最低有效位(LSB)。
REFOUT:控制输出CRC校验值是否进行反转操作。在计算左移后数据多项式模二除以生成多项式后,余数(即CRC校验值)是否按位反转,True或False。
XOROUT:计算结果与此参数异或后得到最终的CRC值。
数据m(x)=0x31 ,CRC-8算法为例,该算法生成多项式G(X)为
.除数p(x)为0b10000 0111。数据m(x)左移八位即x8m(x)=0x3100。 p(x) 模二除以x8m(x)的余数为0x97.
以CRC-16/DNP算法为例,
● 多项式公式G(X)为x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1,除数为p(x)=0x13D65= 0b10011 1101 0110 0101。
● 数据m(x)为=0x31=0b0011 0001。由于CRC-16/DNP模型的输入数据反转,其值RefIn m(x) =0b1000 1100 =0x8C。数据m(x)左移16位即x16RefInm(x)=0x8C0000。
● x16RefIn m(x) = 0x8C0000模二除以p(x) = 0x13D65 的余数为r(x)=0b0101 1001 1011 0101=0x59b5.输出数据翻转RefOut r(x)=0b1010 1101 1001 1010 =0xAD9A。
● 结果异或值XorOut为0xFFFF,CRC-16/DNP算法的CRC值= 结果异或值XorOut 按位异或 输出数据翻转RefOut r(x),即RefOut r(x) ^ XorOut 。其值为0xAD9A ^ 0xFFFF = 0xE265。
传统CRC算法
实际应用时,发送方和接收方按以下方式通信:
发送方和接收方在通信前,约定好一个预设除数P(X)。P(X)首位和最后一位的系数必须为1. 以上面的CRC-8为例,多项式(poly)为X8 + X2 + X +1,对应除数P(X) = 10011.
发送方在发送前,将原始数据左移 除数P(X)的次幂的位,将其值进行模二除法运算生成余数F(X)(即CRC码),然后将其附加到原始数据后面一起T(X)发送给接收方。
接收方收到后将其T(X)模二除以约定好的除数P(X),当且仅当余数为0时接收方认为没有差错.
CRC校验码的编码方法是用待发送的二进制数据D(x)昧以生成多项式G(x),将最后的余数作为CRC校
验码。其实现步骤如下:
①没待发送的数据块是P位的二进制多项式D(x).生成多项式为i阶的G(x)。在数据块的末尾掭加i
个0.数据块的长度增加到m+i位.对应的二进制多项式为xiD(x).
②用生成多项式G(x)去除xiD(x),求得余数为阶数为i-1的二进制多项式R(x)。此二进制多项式R(x)
就是D(x)经过生成多项式G(x)编码的CRC校验码。
③用xiD(x)以模2的方式减去R(x),得到二进制多项式xiD’(x)。xiD’(x)就是包含了CRC校验码的
待发送字符串。
基于查表法的CRC算法
计算机操作单元一般为字节为单位,所以采用一个或者多个字节长度的CRC进行校验传递数据,提高CRC校验速度。 预先将CRC计算出来,并存到校验表里,且校验表存在 该行的首个CRC码与该列的首个CRC码的异或值 与他们交集的CRC码相同,每次调用CRC算法采用查表法替代移位计算发放,可提升计算速度。
以8bit 一个字节长度的CRC为例,有256种情况,对应余数有0~255种,将256种余数分别计算出来,按照顺序存放在一个包含256个入口地址的校验表中,然后对输入数据流采用查表来实现。
设置数据流为,
数学表达式为
,其中⊕为异或运算符。生成多项式为G(x)17bit,则CRC码为CRC16,数学表示式为
CRC校验可以100%地检测出所有奇数个随机错误和长度小于或等于i(i为g(x)的阶数)的突发错误。
所以CRC的生成多项式的阶数越高,那么误判的概率就越小。
参考链接
【科普向】谁都能看懂的CRC(循环冗余校验)原理:https://blog.csdn.net/weixin_44256803/article/details/105805628
什么是CRC:https://info.support.huawei.com/info-finder/encyclopedia/zh/CRC.html
CRC校验查表法原理及实现(CRC-16): https://blog.csdn.net/AgonyRR/article/details/107810982
CRC循环冗余校验 查表算法的代码实现:https://blog.csdn.net/weixin_44256803/article/details/111794445
CRC在线计算: http://www.ip33.com/crc.html
[1]马群,王会燃.基于查表法的嵌入式系统CRC算法研究[J].软件导刊,2014,13(10):51-52.