实用指南:【计算机网络】考研408核心考点|循环冗余码(CRC)详解:从多项式原理到检错纠错实战

差错控制

导读

大家好,很高兴又和大家见面啦!!!

在上一篇内容中,我们一同探讨了数据链路层差错控制的第一道防线——检错编码。我们重点了解了奇偶校验码,它通过便捷的奇偶位设置,为我们提供了一种基础而高效的错误检测手段

然而,正如我们所讨论的,奇偶校验码在检测能力上存在一定的局限:

  • 无法定位错误位
  • 对偶数个比特的错误无能为力

为了解决这些局限,并满足现代通信与存储系统对数据完整性更高标准的要求,一种更强大、更可靠的检错技巧被广泛采用,这就是我们本篇将要深入学习的循环冗余校验码Cyclic Redundancy Check, CRC)。

CRC 以其强大的检错能力和高效的实现,已成为以太网、USB、Wi-Fi等众多核心通信协议和存储系统中不可或缺的差错控制机制

它背后的核心思想,是将数据视为多项式,通过特定的模2除法运算来生成校验码,从而极大地提升了错误检测的可靠性

下面,就让大家正式进入循环冗余码的世界,深入了解其工作原理和卓越特性

一、定义

循环冗余校验码Cyclic Redundancy Code, CRC)是一种基于多项式代数模2运算的差错检测编码方法。它将资料比特序列视为多项式的系数,通过特定的多项式除法来生成校验码。

1.1 多项式代数

任何二进制数据串都可以表示为一个多项式。例如,数据 1101 可以解释为多项式 1 ∗ x 3 + 1 ∗ x 2 + 0 ∗ x 1 + 1 ∗ x 0 1∗x^3+1∗x^2+0∗x^1 +1∗x^01x3+1x2+0x1+1x0 ,即 x 3 + x 2 + 1 x^3+x^2 +1x3+x2+1。生成多项式G ( x ) G(x)G(x) 也是一个二进制序列,例如 1011 表示 x 3 + x + 1 x^3 +x+1x3+x+1

1.2 模2运算

模2运算 (Modulo-2 Arithmetic) 是CRC计算的基础规则,包括:

  • 模2加法0 + 0 = 0 , 0 + 1 = 1 , 1 + 0 = 1 , 1 + 1 = 0 0+0=0, 0+1=1, 1+0=1, 1+1=00+0=0,0+1=1,1+0=1,1+1=0(等同于 逻辑异或XOR)。

  • 模2减法:规则与加法完全相同。

正由于加减法规则一致,模2除法中的每一步相减管理都简化为异或运算。

二、基本思想

循环冗余码CRC)检错的基本思想:

  • 收发双方约定一个生成多项式 G ( x ) G(x)G(x)(要求最低位必须为1 11)。k kk位位串可视为阶数为k − 1 k - 1k1的多项式的系数序列。
  • 发送方基于待发送的资料和G ( x ) G(x)G(x),计算出冗余码,将冗余码附加到数据后面一起发送。
  • 接收方收到资料和冗余码后,利用G ( x ) G(x)G(x)来计算收到的材料和冗余码是否产生差错。

假设一个待传送m mm 位的数据,CRC运算产生一个r rr位的冗余码,称为帧检验序列Frame Check Sequence, FCS)。这样形成的帧将由m + r m + rm+r 位组成。

数据信息
1
0
...
1
帧检验序列
1
0
...
1

在所要发送的数据后面增加r rr位冗余码,就算增大了传输开销,可是允许进行差错检测,这种代价往往是值得的。这个带检验码的帧刚好能被预先确定的多项式G ( x ) G(x)G(x)整除。接收方用相同的多项式去除收到的帧,若余数为0 00,则认为无差错。

2.1 十进制除法

为了更好的理解CRC的基本思想,这里我们以十进制除法来进行类比;

假设通信双方规定了一个除数 5 ,那么对于数据 827 便可通过 十进制除法获取一个余数:

165 5 ) 827 ‾ 5 00 ‾ 32 7 30 0 ‾ 27 0 25 ‾ 2 \begin{array}{rl} 165 \\ 5 \overline{\smash{\big)} 827} \\ \underline{5\phantom{00}} \\ 32\phantom{7} \\ \underline{30\phantom{0}} \\ 27 \\ \underline{\phantom{0}25} \\ \bm{\textcolor{red}{2}} \end{array}1655)827500327300270252

可以看到,若通信双方的数据传输没有发生问题,那么通信双方凭借除法所得余数一定相等;当通信双方所获取的余数不相等时,那就说明传输的数据出现了问题。

CRC采用的就是该思路:

  • 通信双方通过约定一个 “除数
  • 信息位冗余位 作为被除数
    • 信息位 通过添加了 冗余位后,确保通过除法所得的余数位0 00
  • 接收方在收到被除数 后,通过 除法检查其余数是否为0 00
    • 若余数为 0 00,则信息传输正确
    • 若余数不为 0 00,则信息传输错误

2.2 二进制除法

在计算机网络中,其传输的数据均为二进制数据,因此所采用的 “除法” 也是 二进制除法

二进制除法是二进制数的一种基本算术运算,其核心规则与十进制除法相似,都涉及从被除数中不断减去除数的过程。

二进制除法分为两种,一种是用于数值计算的普通二进制除法用于差错控制的就是,另一种模2除法(其核心是异或运算):

  • 普通二进制除法重要分为三步:
    • 比较:判断当前部分被除数是否“大于等于”除数。
    • 试商:根据比较结果决定商1(够减)或商0(不够减)。
    • 减法:执行带借位的二进制减法。

简单的说,普通二进制除法十进制除法 完全一致,这里我们以 1011 除以 11 为例进行说明:

000000 011 ( 商 ) 11 ) 1 0 11 ‾ ( 被除数 : 1011 , 除数 : 11 ) 00000 00 00 ‾ ( 第 1 步 : 10 < 11 , 不够除 , 商 0 ) 1 0 1 0 ( 下移一位 , 当前部分被除数为 101 ) 0 11 0 ‾ ( 第 2 步 : 101 > 11 , 商 1 , 计算 101 − 11 = 10 ) 1 0 1 ( 余数 10 , 下移末了一位 1 , 得 101 ) 00 11 ‾ ( 第 3 步 : 101 > 11 , 商 1 , 计算 101 − 11 = 10 ) 10 ( 最终余数 : 10 ) \begin{array}{lrl} & \phantom{000000}011 & (商) \\ & 11 \enspace\overline{\smash{\big)}\enspace 1\textcolor{red}{0}11} & (被除数: 1011, 除数: 11) \\ & \phantom{00000}\underline{\textcolor{blue}{00}\phantom{00}} & (第1步: 10 < 11, 不够除, 商0) \\ & 1\textcolor{red}{0}1\phantom{0} & (下移一位, 当前部分被除数为 \textcolor{red}{101}) \\ & \underline{\phantom{0}\textcolor{blue}{11}\phantom{0}} & (第2步: 101 > 11, 商1, 计算 101 - 11 = 10) \\ & 1\textcolor{red}{0}1 & (余数10, 下移最终一位1, 得101) \\ & \underline{\phantom{00}\textcolor{blue}{11}} & (第3步: 101 > 11, 商1, 计算 101 - 11 = 10) \\ & \textcolor{red}{10} & (最终余数: \textcolor{red}{10}) \end{array}00000001111)101100000000010100110101001110()(被除数:1011,除数:11)(1:10<11,不够除,0)(下移一位,当前部分被除数为101)(2:101>11,1,计算10111=10)(余数10,下移最后一位1,101)(3:101>11,1,计算10111=10)(最终余数:10)

二进制算术除法10 表示的是十进制中的 211 表示的是十进制中的 3 ,因此我们在理解其具体步骤时,不能将其视为十进制中的1011

  • 模2除法主要分为两步:
    • 判断首位:只看当前部分被除数的最高位。
      • 若为1,则商1;
      • 若为0,则商0
    • 模2减:商1后,执行的操控是异或XOR),即模2减法

这里我们以 1100100 除以 1011 为例来说明 模2除法具体的运算过程:

00000000 1111 ( 商 ) 1011 ) 1 100 100 ‾ ( 除数: 1100100 ,被除数: 1011 ) 00000 1 011 000 ‾ ( 第 1 步: 1100 / 1011 ,首位为 1 ,商取 1 ) 000000 1 11 1 00 ( 下移一位,当前被除数: 1111 ) 00000 0 1011 00 ‾ ( 第 2 步: 1111 / 1011 , 首位为 1 ,商取 1 ) 0000000 1 000 0 ( 下移一位,当前被除数: 1000 ) 00000 00 1011 0 ‾ ( 第 3 步: 1000 / 1011 ,首尾为 1 ,商取 1 ) 00000000 1 110 ( 下移一位,当前被除数: 1110 ) 00000 000 1011 ‾ ( 第 4 步: 1110 / 1011 ,首位为 1 ,商取 1 ) 000000000 101 ( 最终余数: 101 ) \begin{array}{lrl} & \phantom{00000000}1111 & (商) \\ & 1011 \overline{\smash{\big)} \bm{\textcolor{blue}{1}}\textcolor{red}{100}100} & (除数:1100100,被除数:1011) \\ & \phantom{00000}\underline{1\textcolor{red}{011}\phantom{000}} & (第1步:1100 / 1011,首位为1,商取1) \\ & \phantom{000000}\bm{\textcolor{blue}{1}}11\textcolor{red}{1}\phantom{00} & (下移一位,当前被除数:1111) \\ & \phantom{00000}\underline{\phantom{0}1011\phantom{00}} & (第2步:1111/1011,首位为1,商取1) \\ & \phantom{0000000} \bm{\textcolor{blue}{1}}000\phantom{0} & (下移一位,当前被除数:1000) \\ & \phantom{00000}\underline{\phantom{00}1011\phantom{0}} & (第3步:1000 / 1011,首尾为1,商取1) \\ & \phantom{00000000}\bm{\textcolor{blue}{1}}110 & (下移一位,当前被除数:1110) \\ & \phantom{00000}\underline{\phantom{000}1011} & (第4步:1110 / 1011,首位为1,商取1) \\ & \phantom{000000000}\bm{\textcolor{red}{101}} &(最终余数:\bm{\textcolor{red}{101}}) \end{array}0000000011111011)1100100000001011000000000111100000000101100000000010000000000010110000000001110000000001011000000000101()(除数:1100100,被除数:1011)(1步:1100/1011,首位为1,商取1)(下移一位,当前被除数:1111)(2步:1111/1011,首位为1,商取1)(下移一位,当前被除数:1000)(3步:1000/1011,首尾为1,商取1)(下移一位,当前被除数:1110)(4步:1110/1011,首位为1,商取1)(最终余数:101)

现在大家已经区分了两种二进制除法,在 CRC 中使用的 二进制除法 是通过 模2除法达成的差错控制。接下来,我们就来具体了解一下通过模2除法 获取 CRC码的具体过程;

2.3 CRC 码

CRC码信息位校验位两部分组成,而校验位的具体内容则通过CRC运算 获得;

这里我们以传输数据信息:1100100 为例,来说明获取 CRC码的具体过程;

假设通信双方定义的生成多项式为G ( x ) = x 3 + x 2 + 1 G(x) = x^3 + x ^2 + 1G(x)=x3+x2+1,那么具体的过程可以分为三步:

  • 确定 K 、 R K、RKR以及生成多项式对应的二进制码

K = 信息位的长度 = 7 R = 生成多项式的最高次幂 = 3 G ( x ) = 1 ∗ x 3 + 1 ∗ x 2 + 0 ∗ x 1 + 1 ∗ x 0 = 1101 \begin{align*} K &= 信息位的长度 &&= 7 \\ R &= 生成多项式的最高次幂 &&= 3 \\ G(x) &= \bm{\textcolor{red}{1}} * x^3 + \bm{\textcolor{red}{1}} * x^2 + \bm{\textcolor{red}{0}} * x^1 + \bm{\textcolor{red}{1}} * x^0 &&= 1101 \end{align*}KRG(x)=信息位的长度=生成多项式的最高次幂=1x3+1x2+0x1+1x0=7=3=1101

  • 移位,将信息码左移R RR位,并在低位补零

1100100 000 1100100\textcolor{red}{000}1100100000

  • 相除,将通过移位获取的信息码与多项式对应的二进制码进行模2除法

000000000 1001001 1101 ) 1100100000 ‾ 000000 1101 000000 ‾ 0000000 0011 000000 00 0000 0000 ‾ 00000000 0110 000000 00 0000 0000 ‾ 000000000 1100 000000 000 1101 000 ‾ 0000000000 0010 000000 0000 0000 00 ‾ 00000000000 0100 000000 00000 0000 0 ‾ 000000000000 1000 000000 000000 1101 ‾ 0000000000000 101 \begin{array}{lr} \phantom{000000000}1001001\\ 1101 \overline{\smash{\big)}\enspace 1100100000} \\ \phantom{000000}\underline{1101\phantom{000000}} \\ \phantom{0000000}0011 \\ \phantom{000000}\underline{\phantom{00}0000\phantom{0000}} \\ \phantom{00000000}0110 \\ \phantom{000000}\underline{\phantom{00}0000\phantom{0000}} \\ \phantom{000000000}1100 \\ \phantom{000000}\underline{\phantom{000}1101\phantom{000}} \\ \phantom{0000000000}0010 \\ \phantom{000000}\underline{\phantom{0000}0000\phantom{00}} \\ \phantom{00000000000}0100 \\ \phantom{000000}\underline{\phantom{00000}0000\phantom{0}} \\ \phantom{000000000000}1000 \\ \phantom{000000}\underline{\phantom{000000}1101} \\ \phantom{0000000000000}\textcolor{red}{101} \\ \end{array}00000000010010011101)110010000000000011010000000000000001100000000000000000000000001100000000000000000000000000110000000000011010000000000000001000000000000000000000000000001000000000000000000000000000000100000000000000011010000000000000101

通过 模2除法得到的余数为101 \textcolor{red}{101}101 ,因此数据 1100100 所对应的 CRC码1100100 101 1100100\textcolor{red}{101}1100100101

三、检错与纠错

CRC码是一个功能强大的检错编码,它不仅能够准确定位错误,还能够对错误进行纠正;

这里我们还是以上述的CRC码为例,说明其具体的检错纠错 功能;

3.1 检错

3.1.1 检错过程

当通信双方在传输数据时,对于CRC码

1100100 101 1100100\textcolor{red}{101}1100100101

这里我们将其记为:C 10 C 9 C 8 C 7 C 6 C 5 C 4 C 3 C 2 C 1 C_{10}C_9C_8C_7C_6C_5C_4C_3C_2C_1C10C9C8C7C6C5C4C3C2C1

接收方在收到该CRC码之后,会凭借约定的生成多项式 G ( x ) G(x)G(x)对应的二进制码进行模2除法 运算,来验算其余数是否为 0

1001001 1101 ) 1100100101 ‾ 1101 000000 ‾ 0011 00000 0 0000 00000 ‾ 0110 0000 00 0000 0000 ‾ 1100 000 000 1101 000 ‾ 0011 00 0000 0000 00 ‾ 0110 0 00000 0000 0 ‾ 1101 000000 1101 ‾ 000 \begin{array}{lr} & 1001001\\ & 1101\enspace \overline{\smash{\big)}\enspace 1100100101} \\ & \underline{1101\phantom{000000}} \\ & 0011 \phantom{00000} \\ & \underline{\phantom{0}0000\phantom{00000}} \\ & 0110 \phantom{0000} \\ & \underline{\phantom{00}0000\phantom{0000}} \\ & 1100 \phantom{000} \\ & \underline{\phantom{000}1101\phantom{000}} \\ & 0011 \phantom{00} \\ & \underline{\phantom{0000}0000\phantom{00}} \\ & 0110 \phantom{0} \\ & \underline{\phantom{00000}0000\phantom{0}} \\ & 1101 \\ & \underline{\phantom{000000}1101} \\ & \bm{\textcolor{red}{000}} \end{array}10010011101)11001001011101000000001100000000000000001100000000000000011000000001101000001100000000000001100000000000011010000001101000

允许看到,若数据传输未发生错误,则其经过模2除法所得的最终余数为000 \bm{\textcolor{red}{000}}000

当数据在传输的过程中,C 8 C_8C8 发生了比特差错,即原本的 0 变成了 1 ,那么接收方接收到的 CRC码 则变成了 11 1 0100101 11\textcolor{red}{1}01001011110100101,此时当大家通过模2除法 获取余数:

1010100 1101 ) 11 1 0100101 ‾ 1101 000000 ‾ 0 1 11 00000 0 0000 00000 ‾ 1 110 0000 00 1101 0000 ‾ 0110 000 000 0000 000 ‾ 1101 00 0000 1101 00 ‾ 0000 0 00000 0000 0 ‾ 0001 000000 0000 ‾ 001 \begin{array}{lr} & 1010100\\ & 1101\enspace \overline{\smash{\big)}\enspace 11\bm{\textcolor{red}{1}}0100101} \\ & \underline{1101\phantom{000000}} \\ & 0\bm{\textcolor{red}{1}}11 \phantom{00000} \\ & \underline{\phantom{0}0000\phantom{00000}} \\ & \bm{\textcolor{red}{1}}110 \phantom{0000} \\ & \underline{\phantom{00}1101\phantom{0000}} \\ & 0110 \phantom{000} \\ & \underline{\phantom{000}0000\phantom{000}} \\ & 1101 \phantom{00} \\ & \underline{\phantom{0000}1101\phantom{00}} \\ & 0000 \phantom{0} \\ & \underline{\phantom{00000}0000\phantom{0}} \\ & 0001 \\ & \underline{\phantom{000000}0000} \\ & \bm{\textcolor{red}{001}} \end{array}10101001101)11101001011101000000011100000000000000011100000001101000001100000000000000110100000011010000000000000000000010000000000001

此时得到的余数不再是000 \bm{\textcolor{red}{000}}000 而变成了 001 \bm{\textcolor{red}{001}}001

CRC码中,发生比特差错的位置与其通过模2除法获取的余数之间可能通过下表展示:

CRC码余数出错位
110010010 0 110010010\bm{\textcolor{red}{0}}1100100100001 \bm{\textcolor{red}{001}}001C 1 C_1C1
11001001 1 1 11001001\bm{\textcolor{red}{1}}11100100111010 \bm{\textcolor{red}{010}}010C 2 C_2C2
1100100 0 01 1100100\bm{\textcolor{red}{0}}011100100001100 \bm{\textcolor{red}{100}}100C 3 C_3C3
110010 1 101 110010\bm{\textcolor{red}{1}}1011100101101101 \bm{\textcolor{red}{101}}101C 4 C_4C4
11001 1 0101 11001\bm{\textcolor{red}{1}}01011100110101111 \bm{\textcolor{red}{111}}111C 5 C_5C5
1100 0 00101 1100\bm{\textcolor{red}{0}}001011100000101011 \bm{\textcolor{red}{011}}011C 6 C_6C6
110 1 100101 110\bm{\textcolor{red}{1}}1001011101100101110 \bm{\textcolor{red}{110}}110C 7 C_7C7
11 1 0100101 11\bm{\textcolor{red}{1}}01001011110100101001 \bm{\textcolor{red}{001}}001C 8 C_8C8
1 0 00100101 1\bm{\textcolor{red}{0}}001001011000100101010 \bm{\textcolor{red}{010}}010C 9 C_9C9
0 100100101 \bm{\textcolor{red}{0}}1001001010100100101100 \bm{\textcolor{red}{100}}100C 10 C_{10}C10

从上表中大家有发现什么吗?

不同出错位的余数中,大家不难发现,其余数总共有7 \bm{7}7种,若算上正确的000 \bm{\textcolor{red}{000}}000那么在该例子中的余数总共有8 \bm{8}8 种。

这里我也不卖关子了,在CRC码中,其校验位的长度R \bm{R}R与其生成多项式G ( x ) G(x)G(x)的最高次幂相等。

  • 即,在生成多项式G ( x ) = 1 ∗ x 3 + 1 ∗ x 2 + 0 ∗ x 1 + 1 ∗ x 0 G(x) = 1 * x^3 + 1 * x ^2 + 0 * x ^ 1 + 1 * x ^ 0G(x)=1x3+1x2+0x1+1x0中,其最高次幂为3 \bm{3}3 ,则表示 R = 3 R = 3R=3

而对于长度为R \bm{R}R的二进制序列,它能表示的二进制序列总数为2 R \bm{2 ^{R}}2R ,该总数由 2 R − 1 \bm{2^{R} - 1}2R1 个错误序列 + ++一个正确序列00 ⋯ 0 \bm{\textcolor{red}{00\cdots0}}000 组成。

  • R = 3 R = 3R=3时,则说明总共有2 3 = 8 2^3 = 823=8种校验码,那对应的就有2 3 − 1 = 7 \bm{2 ^3 - 1 = 7}231=7 种错误序列 + ++一个正确序列000 \bm{\textcolor{red}{000}}000

当信息位的长度K + \bm{K} +K+校验码的长度R \bm{R}R 所得到的 CRC码 的总长度 K + R ≤ 2 R − 1 \bm{K + R} \leq \bm{2 ^{R} - 1}K+R2R1时,其错误序列会与CRC码中的错误位置一一对应;

  • R = 3 R = 3R=3 时,若 CRC码 的总长度 K + 3 ≤ 7 K + 3 \leq 7K+37 ,即 K ≤ 4 K \leq 4K4时,其错误序列会与CRC码中的错误位置一一对应

  • K > 4 K > 4K>4时,其错误序列可能会对应多个错误位置;

    • 如上述例子中的错误序列001 \bm{\textcolor{red}{001}}001 就对应 C 1 , C 8 C_1, C_8C1,C8两个错误位置;

这里需要注意,我所说的错误序列指的是,当在传输的过程中发生比特差错 时,通过 模2除法 获得的 余数

3.1.2 特点

理论上可以证明CRC的检错能力有以下特点:

  • 可检测出所有奇数个错误
  • 可检测除所有双比特的错误
  • 行检测出所有小于等于校验位长度的连续错误

3.2 纠错

在前面的内容中,我们介绍了CRC码的检错能力,并且当K + R ≤ 2 R − 1 K + R \leq 2^R - 1K+R2R1 时, CRC码允许准确的检测出发生比特差错通过的具体位置,当出错的位置确定后,我们是能够直接对其进行纠错;

3.2.1 纠错过程

CRC码的纠错过程许可总结为4步:

  • 错误检测​:

    • 发现错误:接收方用生成多项式G ( x ) G(x)G(x)对收到的信息进行模2除法,若余数不为0 00,则断定传输有误
  • 循环左移与计算​

    • 定位错误:将接收到的数据循环左移1位,同时将当前的余数补0后,继续与G ( x ) G(x)G(x)进行模2除法,得到新余数
  • 错误位判定​

    • 识别并纠正:重复步骤2,直到余数与“最高位出错”的特定余数相同。此时,错误位已移至数据最高位,将其取反(纠正)
  • 循环右移恢复​

    • 还原数据:将已纠正一位错误的数据循环右移之前左移的总次数,所有比特恢复原始顺序,得到正确的原始数据

3.2.2 纠错核心

CRC,经过对生成多项式就是校验中纠错能力的核心G ( x ) G(x)G(x)构建一个表示错误位置与余数对应关系的字典,从而利用模2除法获取的余数来准确判断发生错误的具体位置;

整个映射关系可以利用模2除法获取,其具体步骤如下:

  • 构建错误图样

假设材料帧中只有一个比特在传输过程中出错。这个错误可以用一个错误图样多项式E ( x ) \bm{E(x)}E(x)来表示,其中只有出错的那一位系数为1 11 ,其余都是 0 00

如对于 生成多项式G ( x ) = x 3 + x + 1 \bm{G(x) = x ^3 + x + 1}G(x)=x3+x+1 而言,其 错误图样多项式E ( x ) \bm{E(x)}E(x) 为:

E ( x 0 ) = x 0 = 000000 1 E ( x 1 ) = x 1 = 00000 1 0 E ( x 2 ) = x 2 = 0000 1 00 E ( x 3 ) = x 3 = 000 1 000 E ( x 4 ) = x 4 = 00 1 0000 E ( x 5 ) = x 5 = 0 1 00000 E ( x 6 ) = x 6 = 1 000000 \begin{align*} E(x_0) &= x ^0 = 000000\bm{\textcolor{red}{1}} \\ E(x_1) &= x ^1 = 00000\bm{\textcolor{red}{1}}0 \\ E(x_2) &= x ^2 = 0000\bm{\textcolor{red}{1}}00 \\ E(x_3) &= x ^3 = 000\bm{\textcolor{red}{1}}000 \\ E(x_4) &= x ^4 = 00\bm{\textcolor{red}{1}}0000 \\ E(x_5) &= x ^5 = 0\bm{\textcolor{red}{1}}00000 \\ E(x_6) &= x ^6 = \bm{\textcolor{red}{1}}000000 \end{align*}E(x0)E(x1)E(x2)E(x3)E(x4)E(x5)E(x6)=x0=0000001=x1=0000010=x2=0000100=x3=0001000=x4=0010000=x5=0100000=x6=1000000

  • 计算余数

错误图样多项式E ( x ) \bm{E(x)}E(x) 除以 生成多项式G ( x ) \bm{G(x)}G(x) ,所得到的 余数多项式S ( x ) \bm{S(x)}S(x)就是该错误位置的唯一“指纹”

S ( x 0 ) = E ( x 0 ) ÷ G ( x ) = 0000001 ÷ 1011 = 001 = 1 S ( x 1 ) = E ( x 1 ) ÷ G ( x ) = 0000010 ÷ 1011 = 010 = x S ( x 2 ) = E ( x 2 ) ÷ G ( x ) = 0000100 ÷ 1011 = 100 = x 2 S ( x 3 ) = E ( x 3 ) ÷ G ( x ) = 0001000 ÷ 1011 = 011 = x + 1 S ( x 4 ) = E ( x 4 ) ÷ G ( x ) = 0010000 ÷ 1011 = 110 = x 2 + x S ( x 5 ) = E ( x 5 ) ÷ G ( x ) = 0100000 ÷ 1011 = 111 = x 2 + x + 1 S ( x 6 ) = E ( x 6 ) ÷ G ( x ) = 1000000 ÷ 1011 = 101 = x 2 + 1 \begin{align*} S(x_0) &= E(x_0) \div G(x) = 0000001 \div 1011 = 001 = 1 \\ S(x_1) &= E(x_1) \div G(x) = 0000010 \div 1011 = 010 = x \\ S(x_2) &= E(x_2) \div G(x) = 0000100 \div 1011 = 100 = x^2 \\ S(x_3) &= E(x_3) \div G(x) = 0001000 \div 1011 = 011 = x + 1\\ S(x_4) &= E(x_4) \div G(x) = 0010000 \div 1011 = 110 = x ^ 2 + x\\ S(x_5) &= E(x_5) \div G(x) = 0100000 \div 1011 = 111 = x ^ 2 + x + 1\\ S(x_6) &= E(x_6) \div G(x) = 1000000 \div 1011 = 101 = x ^ 2 + 1 \end{align*}S(x0)S(x1)S(x2)S(x3)S(x4)S(x5)S(x6)=E(x0)÷G(x)=0000001÷1011=001=1=E(x1)÷G(x)=0000010÷1011=010=x=E(x2)÷G(x)=0000100÷1011=100=x2=E(x3)÷G(x)=0001000÷1011=011=x+1=E(x4)÷G(x)=0010000÷1011=110=x2+x=E(x5)÷G(x)=0100000÷1011=111=x2+x+1=E(x6)÷G(x)=1000000÷1011=101=x2+1

3.2.3 实例说明

接下来我们以传输信息 1101 为例来说明 CRC的纠错过程;

假设通信双方所规定的生成多项式 G ( x ) = x 3 + x + 1 G(x) = x ^3 + x + 1G(x)=x3+x+1,其对应的二进制码为1011 10111011

当前的 K = 4 , R = 3 K = 4, R = 3K=4,R=3 满足 K + R ≤ 2 R − 1 K + R \leq 2^R - 1K+R2R1,因此当前数据在传输过程中发生错误时,所获取的错误序列与其比特位一一对应

根据 模2除法 我们获取的 CRC码 为:1101 001 1101\bm{\textcolor{red}{001}}1101001

我们将此 CRC码 记为:C 7 C 6 C 5 C 4 C 3 C 2 C 1 C_7C_6C_5C_4C_3C_2C_1C7C6C5C4C3C2C1。当在传输的过程中发生错误时,接收方收到的CRC码 为:110 0 001 110\textcolor{red}{0}0011100001

  • 检测错误:

    • 根据 模2除法,获取到的余数为011 \bm{\textcolor{red}{011}}011
    • 该余数不为 0 00说明数据传输发生了比特差错,接下来需要从该余数开始进行纠错
  • 循环左移与计算

    • 将原数据向左移动一位,得到新内容:10 0 0011 10\textcolor{red}{0}00111000011
    • 将获取的余数011 \bm{\textcolor{red}{011}}011,补 0 00 后得到新数 011 0 011\textcolor{red}{0}0110
    • 再将该新数与G ( x ) G(x)G(x) 进行 模2除法,得到新余数:110 \bm{\textcolor{red}{110}}110
  • 错误位判定:

    • 将步骤2获得的余数:110 110110G ( x ) G(x)G(x)对应的最高位出错的特定余数:101 101101 进行比较:110 ≠ 101 110 \neq 101110=101,此时需要继续重复步骤2;
  • 循环左移与计算

    • 将原数据向左移动一位,得到新数据:0 0 00111 0\textcolor{red}{0}001110000111
    • 将获取的余数110 \bm{\textcolor{red}{110}}110,补 0 00 后得到新数 110 0 110\textcolor{red}{0}1100
    • 再将该新数与G ( x ) G(x)G(x) 进行 模2除法,得到新余数:111 \bm{\textcolor{red}{111}}111
  • 错误位判定:

    • 将步骤2获得的余数:111 111111G ( x ) G(x)G(x)对应的最高位出错的特定余数:101 101101 进行比较:111 ≠ 101 111 \neq 101111=101,此时需要继续重复步骤2;
  • 循环左移与计算

    • 将原数据向左移动一位,得到新数据:0 001110 \textcolor{red}{0}0011100001110
    • 将获取的余数111 \bm{\textcolor{red}{111}}111,补 0 00 后得到新数 111 0 111\textcolor{red}{0}1110
    • 再将该新数与G ( x ) G(x)G(x) 进行 模2除法,得到新余数:101 \bm{\textcolor{red}{101}}101
  • 错误位判定:

    • 将步骤2获得的余数:101 101101G ( x ) G(x)G(x)对应的最高位出错的特定余数:101 101101 进行比较:101 = 101 101 = 101101=101,说明当前的最高位就是发生错误的内容;
    • 此时需要将最高位的比特进行按位取反,得到新的数据:1 001110 \textcolor{red}{1}0011101001110,达成错误纠正
  • 循环右移恢复:

    • 完成数据纠正后,需要将以纠正一位错误的内容循环右移之前左移的总次数3 \bm{3}3次,得到正确的原始数据:110 1 001 110\textcolor{red}{1}0011101001

四、小结

CRC 虽然具有 纠错功能但是其纠错的条件十分苛刻,只有满足:K + R ≤ 2 R − 1 K + R \leq 2^R - 1K+R2R1 且只发生了 单比特差错时,才能对其进行纠错;

因此在实际的使用过程中,CRC主导被用作一种高效的错误检测机制而非纠错机制

  • 当检测到错误时,通过丢弃错误帧并要求发送方重传帧 来实现 差错控制

这种“检错+重传”的策略,在实践中远比尝试让接收端自行纠错更加可靠和高效。

结语

依据今天的学习,我们共同深入探讨了数据链路层中至关重要的差错控制技术——循环冗余校验码CRC)。现在,让我们一同回顾本次旅程的核心要点,为您梳理和巩固知识体系。

首先,我们明确了CRC的核心定义:

  • 它是一种基于多项式代数模2运算(本质是异或运算)的差错控制编码
  • 发送方和接收方预先约定一个生成多项式G ( x ) \bm{G(x)}G(x)将待发送的材料视为一个多项式,通过特定的模2除法 运算来 生成校验码

其核心工作流程可以概括为三步:

  • 移位:发送方在数据位后补R RR0 00R RR为生成多项式的最高次幂)
  • 相除:用 生成多项式 对其进行 模2除法,得到的余数(即帧检验序列FCS
  • 拼接:将 FCS附加在原始数据后一同发送。

接收方进行相同的计算:

  • 若余数为 0 00,则认为传输无误
  • 若非 0 00,则断定传输出错。

CRC最显著的优势在于其强大的检错能力。理论上,一个设计良好的CRC能够:

  • 检测出所有奇数个比特错误
  • 检测出所有双比特错误
  • 检测出所有长度小于或等于校验位长度的突发性错误

正因如此,其错误漏检率极低,使其在以太网、Wi-Fi、USB、磁盘存储等众多领域成为不可或缺的可靠性保障。

虽然 CRC 在满足 K + R ≤ 2 R − 1 \bm{K+R \leq 2^R −1}K+R2R1 条件下能够纠正单比特错误,但应该注意的是,在实际的网络通信协议中,“检错”而非“纠错”的角色就是CRC 主要扮演的。一旦检测到错误,标准做法是丢弃错误资料并请求发送方重传ARQ机制),这种“检错重传”策略在实践中通常比尝试自行纠错更为高效和可靠。

总而言之,循环冗余校验码以其优雅的数学原理、强大的错误检测能力和高效的实现方式,成为了确保数据在不可靠信道上准确传输的基石技能。

希望本篇内容能帮助您不仅理解其计算步骤,更能领会其设计思想与应用场景。

互动与分享

  • 点赞 - 您的认可是我持续创作的最大动力

  • 收藏⭐ - 方便随时回顾这些核心的基础概念

  • 转发↗️ - 分享给更多可能需要的朋友

  • 评论 - 欢迎留下您的宝贵意见或想讨论的话题

感谢您的耐心阅读! 关注博主,不错过更多工艺干货。我们下一篇再见!

posted on 2025-12-15 08:05  ljbguanli  阅读(180)  评论(0)    收藏  举报