3.3 循环冗余校验码的原理(P76 3.1.2)
数据链路层广泛采用了**循环冗余校验 CRC(Cyclic Redundancy Check)**来进行差错检测。
CRC 校验就是给数据部分后面填上 位冗余码,并约定一个 位的除数 用于计算冗余码, 的值决于具体使用的 CRC 校验方法,例如(P77 3.1.1):
- CRC-3:,使用多项式 ,除数 为 。
- CRC-16/IBM:,使用多项式 ,除数 为
- CRC-16/CCITT:,使用多项式 ,除数 为
- CRC-32:,使用多项式 ,除数 为 ,这也是 Ethernet 所使用的方法。
由于除数 最高位必是 ,因此常见的表示方式是省略最高位,例如 CRC-16/CCITT 的除数 一般表示为 。
首先选定 CRC 校验的算法,假设选中的算法生成 位校验码,则除数 为 位,假设待校验的数据为 M 位的二进制数据,则具体计算步骤如下:
-
首先将原始数据左移 位得到数据 ,即空出 位校验码的位置。
-
取 前 位,得到被除数 。
-
对被除数 执行以下操作:
- 若最高位为 ,则与除数 进行异或。
- 若最高位为 ,则与 进行异或。
得到 4 位结果 ,取其后 3 位得到 (由于这一步计算的特性, 的最高位一定是 )。
-
提取 的下一位,追加到结果 的尾部,得到新的被除数 ,再次执行步骤 3。
-
直到计算 的最后一位,记最后一次异或的结果 为 ,余数 即为冗余码。
具体的,假设使用 CRC-3,则除数为 4 位的 ,需要生成 3 位的冗余码,假设待校验的数据为 ,则:
101001
---------
101001000
1011
---------
0010
0000
---------
0101
0000
---------
1010
1011
---------
0010
0000
---------
0100
0000
---------
100
解释如下:
- 首先将原始数据左移 3 位,即空出 3 位校验码的位置,得到数据 :。
- 取 前 4 位:,记为 。
- 此时 最高位为 ,则将其与除数 做异或操作,即 ,得到结果 ,取其后三位 记为 。
- 提取 第 5 位(即 ),追加到 尾部,得到 ,记为新的 。
- 此时 最高位为 ,则将其与 做异或操作,即 ,得到结果 ,取其后三位 记为 。
- 提取 第 6 位(即 ),追加到 尾部,得到 ,记为新的 。
- 此时 最高位为 ,则将其与 做异或操作,即 ,得到结果 ,取其后三位 记为 。
- 提取 第 7 位(即 ),追加到 尾部,得到 ,记为新的 。
- 此时 最高位为 ,则将其与除数 做异或操作,即 ,得到结果 ,取其后三位 记为 。
- 提取 第 8 位(即 ),追加到 尾部,得到 ,记为新的 。
- 此时 最高位为 ,则将其与 做异或操作,即 ,得到结果 ,取其后三位 记为 。
- 提取 第 9 位(即 ),追加到 尾部,得到 ,记为新的 。
- 此时 最高位为 ,则将其与 做异或操作,即 ,得到结果 ,取其后三位 记为 。
- 此时已计算到最后一位,记 (即 )为 , 即为冗余码。
得到冗余码为 ,发送数据时将冗余码 追加到数据结尾即可。
这种方式看似很复杂,但由于网络设备发送数据也是一位一位按顺序发送,因此在硬件上很容易能实现这种算法,当数据发送完的时候,冗余码也就计算完成,直接继续发送冗余码即可。
接收方校验时,直接将接收到的数据记为 ,然后从冗余码计算方法的第二步开始计算,若最终结果为 ,则代表数据无误。
Ethernet 所使用的 CRC 校验算法为 CRC-32,检测率非常接近 100%,(P77 3.1.1)即:“凡事接收端数据链路层接受的帧,我们都能以非常接近 1 的概率认为这些帧在传输过程中没有产生差错。”