数据链路层CRC(循环冗余码)差错校验码详解
CRC
差错校验码是数据链路层用来进行差错校验的一个码。
CRC编码过程
假设要编码的数据D
,有d个比特
,发送节点要将它发送给接收节点。发送方和接收方要先协商一个r + 1
比特模式,成为生成多项式
。我们将其表示为G
。我们将要求G的最高有效位(最左边)的比特是1。
我们要有一个数据D,比如 1001
这个数据有d个比特,也就是4个比特
需要附加 r 个比特作为校验码 R
编码过后会变成数据会变成D + R
数据有d + r个比特
使得得到的数据D+R进行模2运算恰好能被G整除
CRC差错检测过程
接收方用G去除接收到的D+R数据,如果余数为非0,则有差错,如果余数为0,则无差错
CRC计算
所有CRC计算采用模2算术来做,在加法中不进位,在减法中不借位。这意味着加法和减法是相同的,而且这两种操作等价于异或
(XOR)操作。
1011 XOR 0101 = 1110
异或
操作:不同的为1,相同为0。也就是0 XOR 0 = 0,1 XOR 1 = 0,0 XOR 1 = 1。
乘法和除法是相同的。
给定D 和 R, D * 2r XOR R就等于 D + R数据。
如何计算R
我们要求出R使得对于n有:
D * 2r XOR R = nG
也就是说,我们要选择 R 使得G能除 D * 2r XOR R 而没有余数。如果对上面的等式两边都 XOR R.
D * 2r = nG XOR R
根据上面的等式可以得出,如果我们用G 除 D * 2r,余数刚好是R
R = remainder (D * 2r / G)
也就是使用D * 2r去除以 G。余数就是R。
如何计算G
G 作为多项式,有两种写法,一种是x2 + x + 1的写法,一种是二进制写法 111。
我们需要用 D * 2r 除以 G 。所以我们需要求出G的二进制写法,才能做除法运算。
这个转换的方法:
- 首先把末尾的1看成x0,也就是x的0次幂
- 这样提取出x的所有幂
- 对应幂的位置填1,如果没有对应幂的位置则填0
转换例子1
G = x4 + x + 1
提取出来的幂分别是 4,1,0。
没有的幂是3,2。
在对应的位置填上1或0。
4 3(无) 2(无) 1 0
1 0 0 1 1
这个G的二进制就是 10011。
其实很简单,0次幂对应个位,1次幂对应十位,一直往上加就行了,有1次幂十位就是1,没有就是0.
转换例子2
G = x6 + x4 + x2 + 1
6 5(无) 4 3(无) 2 1(无) 0
1 0 1 0 1 0 1
对应的二进制就是 1010101
计算CRC编码
给定 D = 101110, G = 1001, d = 6, r = 3。计算D的CRC编码后的数据
首先求R。
用D/G可以得出结果为101011,余数为011,余数就是R。
然后把R放到D后面。
编码后就是 101110 011