奇偶校验/累加和校验/CRC校验
何为CRC
简介
CRC即循环冗余校验码(Cyclic Redundancy Check)是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
原理
CRC 算法的基本思想是将传输的数据[M(X)] 当做一个位数很长的数。将这个数除以另一个数[G(X)] ,得到的余数[R(X)] 作为校验数据附加到原数据后面,组成循环校验码。
M(X) 代表待编码的有效信息
G(X) 代表约定好的多项式
R(X) 代表代表检验位
- 1
- 2
- 3
由于,CRC的结构 = 信息位(N位) + 校验位(K位)
所以,CRC编码 = M(X) + R(X)
CRC编码方法
-
把待编码的N位有效信息位表示为多项式
M(X) -
把
M(X)左移K位,得到M(X)*X^K,这样就空出了K位,以便拼接K位余数,这里的K位是由多项式G(X)的最高位决定的 -
选取一个生成多项式
G(x),对M(X)*X^K做模二除 (多项式G(X)一般会直接给你,模二除看下面例子,实质是异或运算),以下是运算公式( M(X) * X^K ) / G(X) = Q(X) + R(X) / G(X)
这里的Q(X)是商,它本身不重要,这里最重要的是求出余数R(X) -
将信息位
M(X)与余数R(X)拼接起来,构成CRC循环冗余校验码
CRC编码 = M(X) + R(X)
常见的校验
奇偶校验
为了解决数据传输过程中可能存在数据错误的问题,有人提出了一种比较简单的方式——奇偶校验法。
奇偶校验主要原理如下:
在原始数据流的头部或者末尾添加一位bit,此bit用于校验此数据包的正确与否。
例如
| 原始码 | 奇校验(奇数个1) | 偶校验(偶数个1) |
|---|---|---|
| 1011000 | 10110000 | 10110001 |
| 1010000 | 10100001 | 10100000 |
优缺点
奇偶校验法优点:
- 原理简单,实现方便。
奇偶校验法缺点:
- 奇偶校验的检错率只有50%,因为只有奇数个数据位发生变化能检测到,如果偶数个数据位发生变化,奇偶校验方式不能检测出错误。
- 奇偶校验每传输一个字节都需要加一位校验位,对传输效率影响很大。
- 奇偶校验只能发现错误,但不能纠正错误,也就是说它只能告诉你出错了,但不能告诉你怎么出错了,一旦发现错误,只好重发。
累加和校验
所谓的累加和校验有很多种,最常见的一种是在每次通信数据包最后都加一个字节的校验数据,这个校验字节里的数据是通信数据包里所有数据的不进位累加和。

比如下面的例子:
我们要传输的信息为: 6、23、4
加上校验和后的数据包:6、23、4、33
这里 33 为前三个字节的校验和。 接收方收到全部数据后对前三个数据进行同样的累加计算,如果累加和与最后一个字节相同的话就认为传输的数据没有错误。
累加和校验由于实现起来非常简单,也被广泛的采用。但是这种校验方式的检错能力也比较一般,对于单字节的校验和大概有1/256 的概率将原本是错误的通讯数据误判为正确数据。 之所以这里介绍这种校验,是因为CRC校验在传输数据的形式上与累加和校验是相同的,都可以表示为:通讯数据 校验字节(也可能是多个字节)
优缺点
- 实现起来方便简单,被广泛运用。
- 检错率一般,例如一个字节多1,一个字节少1,则会出现误判。
- 和奇偶校验一样,只能发现错误,但不能纠正错误。
海明码校验
你看得懂的海明码校验和纠错原理 (在另一篇重单独介绍)
CRC校验
模2除法
基于有限域GF(2)(即除以2的同余)的多项式环。
先说下什么是“模2除法”,我们知道模2加减是不进位、不借位的加减法,比如1+1=0,1+0=1,101+011=110,等于每一位的异或运算,相同bit加减为0,不同bit加减则为1。模2除法同理,即当部分余数首位是1时商取1,反之商取0。然后每一位的减法运算是按位减,不产生借位。余数的位数一定要是比除数位数只能少一位,哪怕前面位是0,甚至是全为0(附带好整除时)也都不能省略。举例如下图所示。

CRC校验码的计算示例
现假设选择的CRC生成多项式为G(X) = X4 + X3 + 1,要求出二进制序列10110011的CRC校验码。下面是具体的计算过程:
- 首先把生成多项式转换成二进制数,由G(X) = X4 + X3 + 1可以知道(,它一共是5位(总位数等于最高位的幂次加1,即4+1=5),然后根据多项式各项的含义(多项式只列出二进制值为1的位,也就是这个二进制的第4位、第3位、第0位的二进制均为1,其它位均为0)很快就可得到它的二进制比特串为11001。
- 因为生成多项式的位数为5,根据前面的介绍,得知CRC校验码的位数为4(校验码的位数比生成多项式的位数少1)。因为原数据帧10110011,在它后面再加4个0,得到101100110000,然后把这个数以“模2除法”方式除以生成多项式,得到的余数(即CRC码)为0100,如图5-10所示。注意参考前面介绍的“模2除法”运算法则。
-
![]()
- 把上步计算得到的CRC校验0100替换原始帧101100110000后面的四个“0”,得到新帧101100110100。再把这个新帧发送到接收端。
- 当以上新帧到达接收端后,接收端会把这个新帧再用上面选定的除数11001以“模2除法”方式去除,验证余数是否为0,如果为0,则证明该帧数据在传输过程中没有出现差错,否则出现了差错。
CRC校验电路原理图

常见CRC参数模型
| CRC算法名称 | 多项式公式 | 宽度 | 多项式 | 初始值 | 结果异或值 | 输入反转 | 输出反转 |
|---|---|---|---|---|---|---|---|
| CRC-4/ITU | x4 + x + 1 | 4 | 03 | 00 | 00 | true | true |
| CRC-5/EPC | x5 + x3 + 1 | 5 | 09 | 09 | 00 | false | false |
| CRC-5/ITU | x5 + x4 + x2 + 1 | 5 | 15 | 00 | 00 | true | true |
| CRC-5/USB | x5 + x2 + 1 | 5 | 05 | 1F | 1F | true | true |
| CRC-6/ITU | x6 + x + 1 | 6 | 03 | 00 | 00 | true | true |
| CRC-7/MMC | x7 + x3 + 1 | 7 | 09 | 00 | 00 | false | false |
| CRC-8 | x8 + x2 + x + 1 | 8 | 07 | 00 | 00 | false | false |
| CRC-8/ITU | x8 + x2 + x + 1 | 8 | 07 | 00 | 55 | false | false |
| CRC-8/ROHC | x8 + x2 + x + 1 | 8 | 07 | FF | 00 | true | true |
| CRC-8/MAXIM | x8 + x5 + x4 + 1 | 8 | 31 | 00 | 00 | true | true |
| CRC-16/IBM | x16 + x15 + x2 + 1 | 16 | 8005 | 0000 | 0000 | true | true |
| CRC-16/MAXIM | x16 + x15 + x2 + 1 | 16 | 8005 | 0000 | FFFF | true | true |
| CRC-16/USB | x16 + x15 + x2 + 1 | 16 | 8005 | FFFF | FFFF | true | true |
| CRC-16/MODBUS | x16 + x15 + x2 + 1 | 16 | 8005 | FFFF | 0000 | true | true |
| CRC-16/CCITT | x16 + x12 + x5 + 1 | 16 | 1021 | 0000 | 0000 | true | true |
| CRC-16/CCITT-FALSE | x16 + x12 + x5 + 1 | 16 | 1021 | FFFF | 0000 | false | false |
| CRC-16/X25 | x16 + x12 + x5 + 1 | 16 | 1021 | FFFF | FFFF | true | true |
| CRC-16/XMODEM | x16 + x12 + x5 + 1 | 16 | 1021 | 0000 | 0000 | false | false |
| CRC-16/DNP | x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1 | 16 | 3D65 | 0000 | FFFF | true | true |
| CRC-32 | x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 | 32 | 04C11DB7 | FFFFFFFF | FFFFFFFF | true | true |
| CRC-32/MPEG-2 | x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 | 32 | 04C11DB7 | FFFFFFFF | 00000000 | false | false |
CRC算法参数模型解释
NAME:参数模型名称。
WIDTH:宽度,即CRC比特数。
POLY:生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。
INIT:这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。
REFIN:待测数据的每个字节是否按位反转,True或False。
REFOUT:在计算后之后,异或输出之前,整个数据是否按位反转,True或False。
XOROUT:计算结果与此参数异或后得到最终的CRC值。


浙公网安备 33010602011771号