
上一篇我们把 IP 数据报封装成了帧,并在帧尾部留下了差错检测字段。这样做的原因很现实:网线、光纤和无线链路都不是理想介质,信号会受到衰减、噪声和干扰,传输中的比特可能发生翻转。
如果一个比特从 0 变成 1,或从 1 变成 0,这类错误称为比特差错。数据链路层必须想办法发现它,必要时还要修复它或请求重传。
奇偶校验、校验和和 CRC 都会在原始数据之外加入冗余信息,但它们的检错能力、计算方式和使用场景差别很大。本文围绕这些方法建立一条主线:先区分检测和纠正,再理解各种校验码如何工作,最后说明发现错误之后网络通常怎样处理。
一、先分清:检错、纠错、ARQ 与 FEC
1. 检错不等于纠错
差错检测只能回答"数据是否可能出错",不能直接指出是哪一位错了,更不能自行恢复正确数据。
差错纠正除了发现错误,还能定位可纠正范围内的错误位置,并恢复原始数据。它需要更有结构的冗余信息,因此通常占用更多带宽和计算资源。
text
检错:发现"这帧有问题"
纠错:发现"第几个位置有问题",并把它改回来
- 简单差错检测技术 :(仅限于比特差错)
- 奇偶校验、循环冗余校验(CRC) 、二维奇偶校验、校验和
- 差错纠正技术:海明码 (属于一种FEC码)
2. ARQ:发现错误后请求重传
自动重传请求(Automatic Repeat reQuest,ARQ)是一种常见的差错控制机制。接收方利用 CRC、校验和等检错方法发现帧错误后,丢弃错误帧,并通过确认、否认确认、超时等机制让发送方重新发送。
ARQ 的特点是接收端不必自己修复错误,但需要等待重传。停止等待、回退 N 帧和选择重传都属于这一类思路,后续在可靠传输内容中还会遇到。
ARQ机制 主要依赖于 检错码 (如CRC、校验和)来工作。
3. FEC:提前加入可纠错冗余
前向纠错(Forward Error Correction,FEC)在发送前加入足够的冗余信息,使接收端即使不能请求或等待重传,也能在一定范围内恢复错误数据。
海明码是理解 FEC 的经典例子。它可以定位并纠正单比特错误;实际无线、卫星和实时媒体系统中,还会使用更复杂的纠错码。
FEC 不是"免费可靠性"。冗余越多,能纠正的错误通常越多,但有效载荷比例、编码复杂度和时延也会增加。实际系统常按场景在 FEC 与 ARQ 之间权衡,甚至两者结合使用。
FEC机制 主要依赖于 纠错码 (如海明码)来工作
二、校验码的共同思想:用冗余发现不一致
无论是奇偶校验、校验和还是 CRC,发送端都会从原始数据计算出额外的校验信息,与数据一起发送;接收端再使用同一规则计算或验证。
text
发送端:原始数据 -> 计算校验信息 -> 数据 + 校验信息
接收端:收到的数据 + 校验信息 -> 按相同规则验证 -> 接受或判错
校验信息本身不携带新的业务内容,却使接收端能够发现数据是否破坏了双方约定的数学关系。因此它也被称为冗余信息。
需要牢记:任何有限长度的检错码都可能存在特定错误模式未被发现。工程目标通常不是追求数学上的"绝对零漏检",而是以合理开销把漏检概率降到足够低。
三、奇偶校验:最简单的一位检错码
1. 奇校验和偶校验怎样构造?
奇偶校验只添加一个校验位,使整个码字中 1 的个数满足约定的奇偶性。
- 偶校验 :包括校验位在内,
1的总数为偶数; - 奇校验 :包括校验位在内,
1的总数为奇数。
例如,数据 1001101 中有 4 个 1:
- 使用偶校验时,校验位为
0,得到10011010; - 使用奇校验时,校验位为
1,得到10011011。
接收端只需检查收到的全部位中 1 的个数是否仍满足约定即可。
2. 为什么异或适合做奇偶校验?
按位异或^,也可能用 ⊕ 表示,不同为1,其余都是0
txt1⊕1=0 0⊕0=0 1⊕0=0⊕1=1a⊕0=a
a⊕1=~a(对a取反)
异或运算满足交换律 和结合律 ,具有自反性。
- 自反性 :a⊕b⊕b=a 对于a,用同样的的运算因子做两次异或之后可以得到a本身,即异或运算的逆运算是自己。
由以上性质可以得出
- 连续多个0异或 结果一定是0
- 连续多个1异或,结果取决于1的个数:奇数个1 结果为1;偶数个1 结果为0
多个1和多个0异或 等同于 这多个1异或的结果(可以把1跟0分别都交换到一起,连续多个0是0):
- 1⊕1⊕0⊕1⊕0⊕1⊕0⊕0⊕0⊕1⊕0⊕1⊕0⊕1=1⊕1⊕1⊕1⊕1⊕1⊕1=1
按位异或可以快速得到一串比特的奇偶性:
text
0 XOR 0 = 0 1 XOR 1 = 0
0 XOR 1 = 1 1 XOR 0 = 1
连续异或一串比特时,结果为 1 表示其中 1 的个数为奇数,结果为 0 表示其中 1 的个数为偶数。硬件可以用异或门高效实现,因此奇偶校验开销极低。
3. 奇偶校验具体操作
奇校验

偶校验

4.局限性
局限性很明显,奇偶校验仅能检测奇数个比特错误,对偶数个错误"视而不见"。例如,若数据帧中两个比特同时翻转(如"1010"变为"0101"),偶校验仍会显示正确。这种"未检出差错"在突发错误场景下尤为危险。
为弥补这一缺陷,工程师在实践中常采用组合策略,比如跟CRC或者重传机制结合。
奇偶校验如同**"第一道防线",在数据传输中快速筛查单比特错误**。尽管无法应对复杂场景,但其低成本、低延迟的特点使其在特定领域(如工业控制、低端物联网)持续发挥作用。随着技术发展,更复杂的校验方案(如CRC、FEC)逐渐取代它,但奇偶校验的简单逻辑仍为理解差错检测提供了直观的起点。
在现实网络中,比特错误往往以突发形式出现(如雷电干扰导致连续多个比特翻转),而非独立随机分布。比如雷电击中电缆时,可能引发数十个连续比特错误。为应对突发差错,实践中广泛采用更复杂的检测技术。
四、二维奇偶校验与海明码:从检测走向定位
1. 二维奇偶校验如何增强能力?
其核心思想是将数据比特组织成一个二维矩阵(i行j列),并对每行和每列分别计算奇偶校验位。
校验位有i+j+1位。+1是因为每行的校验数据在最后一列 对这一列也要算列校验位。

若只有一个比特出错,它所在的行和列都会校验失败,二者的交点就能定位错误位置并将其翻转回来。因此,二维奇偶校验可以纠正单比特差错。
对于两个比特错误,它通常能发现有问题,但无法唯一确定应修复哪两个位置;更多错误则可能存在无法检测的组合。
它展示了一个重要思想 :增加冗余维度,可以从"发现错误"进一步走向"定位错误"。我们还是把这个归为检错码
例子:如果保证只能有1个比特出现问题,那么就可以确定问题
一个比特位会分别被行校验和列校验 ,校验两次。因此如果一个比特位差错时,其所在的行校验和列校验的故障字S都==1,此时可定位到出错的比特,并且进行纠正,无需重传。例子:检测但不能纠正分组中2个比特的差错
- 原因:出错的在不同的行不同的列,有多个交点无法确定
再多的就不一定能检测出来了。比如3比特 4比特。。。。
2. 海明码为什么能纠正单比特错误?
海明码把多个校验位放在特定位置,每个校验位负责检查一组数据位。接收端重新检查后得到的故障字,可以直接表示发生单比特错误的位置。
若信息位有 mmm 位,校验位有 rrr 位,为了表示"无错误"和所有可能的单比特错误位置,需要满足:
2r≥m+r+1 2^r \geq m + r + 1 2r≥m+r+1
标准海明码能够纠正 1 位错误,并能检测 2 位错误,但不能在不增加额外保护位的情况下同时可靠完成"纠正 1 位"和"检测所有 2 位错误"。
本篇不展开海明码的逐位编码过程,重点是建立概念:纠错码必须让不同错误位置 产生可区分的校验结果,才能定位并修复。
五、校验和:按固定字长累加后取反
1. 校验和的基本思路
校验和将数据切分成若干个固定长度的字,按照约定进行累加,再对结果取反或补码形成校验字段。接收端对收到的数据和校验字段再次做同样计算,检查结果是否符合约定。
网络协议中常见的是一补码校验和:把若干固定长度的字进行一补码加法,最后取反。IPv4 首部校验和、TCP/UDP 校验和都使用与这种思路相关的机制。
它可以用一个小例子理解:
text
数据字 1 + 数据字 2 + ... + 校验和
↓
接收端重新累加后,应得到约定的全 1 结果
2. 校验和的特点与局限
校验和比单一奇偶校验更能发现多种错误,计算也比 CRC 的多项式除法直观。但它本质上仍是较简单的代数关系,一些互相抵消的错误模式可能逃过检测。
因此,校验和常用于 IP、TCP、UDP 等协议的端到端或首部完整性检查;在以太网这类链路层帧的强检错场景中,CRC 更常见。
六、CRC:用模 2 除法构造高强度检错码
1. CRC 的核心目标
循环冗余校验 (Cyclic Redundancy Check,CRC)把数据比特串视为二进制多项式,并使用收发双方预先约定的生成多项式进行模 2 除法。
发送端生成一段冗余码,常称帧检验序列 (Frame Check Sequence,FCS),附在数据尾部。
这个冗余码被构造为:完整发送帧能够被生成多项式整除。
接收端用同一个生成多项式去除整个收到的帧:
- 余数为
0:认为帧未检测到错误; - 余数非
0:判定帧出现错误并按协议处理。
循环冗余校验CRC的基本思想如下:
-
收发双方约定好一个生成多项式G(x)。要求G(x)中一定要含有x0(也就是1)
怎么约定? -> 两个电脑通过同一个算法得出同样的G(x),而不是互相发送
-
发送方基于待发送的数据和生成多项式 G(x),通过模2除法计算出差错检测码,即冗余码(帧检验序列FCS),将冗余码添加到待发送数据的后面一起传输。
-
接收方收到数据和冗余码后,通过生成多项式G(x)来计算收到的数据和冗余码是否产生了误码。
2. 模 2 运算是什么?
模2算术是循环冗余检测(CRC)的数学基石,其核心特性 是加法不进位 、减法不借位,因此它们都等价于异或运算:
- 在模2加法中,不进位(即1+1=0,而非10)。
- 在模2减法中 ,不借位(即0-1=1),结果与加法相同。
- 在模2运算中,二进制加法与减法完全等价于异或操作(相同就是0,不同就是1)。
- 模2除法:除法过程中,相减时不借位。
- 乘2^i次方,相当于补充i个0(二进制)
模 2 除法的过程与普通长除法形式相似,但每一步"相减"实际执行的是异或。这个性质使 CRC 可以用移位寄存器和异或门高速实现,十分适合网卡等硬件在线处理。
3. 发送端怎样生成 FCS?
设生成多项式最高次数为 rrr,其对应的二进制位串长度为 r+1r+1r+1。发送端的步骤是:
- 在原始数据 DDD 后补 rrr 个
0,为 FCS 预留位置; - 用生成多项式对应的位串对补零后的数据做模 2 除法;
- 得到不超过 rrr 位的余数 RRR;
- 将 RRR 放到原来补零的位置,形成最终发送帧。
用多项式形式表示:
D⋅2r=Q⋅G+R D \cdot 2^r = Q \cdot G + R D⋅2r=Q⋅G+R
在模 2 运算中,加法和减法等价,因此发送的完整比特串为:
D⋅2r+R=Q⋅G D \cdot 2^r + R = Q \cdot G D⋅2r+R=Q⋅G
它是 GGG 的整数倍,所以接收端在数据未被破坏时用 GGG 去除,余数必为 0。
4.具体例子
发送方
具体步骤如下:
(1)将待发送的数据作为被除数的一部分,后面添加生成多项式G(x)最高次个0以构成被除数。
(2) 生成多项式G(X)各项系数构成的比特串作为除数。
(3)进行二进制模2除法,得到商和余数。余数就是所计算出的冗余码。冗余码的长度应与生成多项式G(x)最高次数相同。
(4) 将冗余码添加到待发送数据的后面一起发送。

接收方
具体步骤如下:
(1) 将收到的数据和冗余码作被除数。
(2) 生成多项式G(x)各项系数构成的比特串作为除数。
(3)进行二进制模2除法,得到商和余数。
(4)如果余数为0,就可判定数据和冗余码中未出现误码。如果余数不为0,则可判定数据或冗余码中出现了误码。

5. CRC 能检测什么错误?
CRC 的检错能力取决于生成多项式。合理选择生成多项式后,CRC 对单比特错误、许多多比特错误和突发错误都有很强的检测能力。
若生成多项式的最高次数为 rrr,CRC 能保证检测长度不超过 rrr 的所有突发错误;对于更长的突发错误,漏检概率也会随着 rrr 增大而迅速降低。以太网使用的 CRC-32 就是典型例子。
因此,CRC 的实际意义不是"证明绝对没有错误",而是以很低的成本把未检测到错误的概率降到极低。接收端通过 CRC 后接受的帧,可以以非常高的概率认为在链路上传输正确。
6. CRC 通常怎样处理错误?
在常见数据链路层用法中,CRC 的主要职责是检错而不是直接纠错。帧校验失败时,接收端通常丢弃该帧;是否重传取决于具体链路协议或更高层的可靠传输机制。
有些编码理论或特定系统可以利用综合信息尝试定位部分错误,但这不是以太网 FCS/CRC 的通常工作方式。将"CRC 检错"直接理解成"CRC 自动纠正错误"会混淆检错码与纠错码的职责。
七、奇偶校验、校验和与 CRC 怎么选?
| 方法 | 冗余信息 | 基本运算 | 检错能力 | 常见使用位置 |
|---|---|---|---|---|
| 奇偶校验 | 1 位 | 异或/统计 1 的个数 | 能发现奇数个比特错误,漏掉偶数个错误 | 简单设备、基础教学场景 |
| 二维奇偶校验 | 多行列校验位 | 行列奇偶校验 | 可纠正单比特错误;可发现部分多比特错误 | 纠错思想的基础示例 |
| 校验和 | 固定长度校验字段 | 一补码加法等 | 比奇偶校验强,但存在抵消型漏检模式 | IP、TCP、UDP 的完整性检查 |
| CRC | 与生成多项式相关的 FCS | 模 2 除法/异或 | 对常见和突发错误检出能力很强 | 以太网及多种链路层协议 |
没有一种方法在所有场景中都"最好"。高速有线链路通常偏好硬件易实现、检错强的 CRC;无线和高时延链路更可能加入 FEC,减少等待重传的代价;端到端协议则会保留校验和、确认和重传等多层保护。
八、结合真实网络理解:错误发生后谁来负责?
假设笔记本通过 Wi-Fi 上传文件:
- 无线信号受干扰,一个 Wi-Fi 帧中的比特发生翻转;
- 接收端依据帧校验发现错误,丢弃该帧;
- Wi-Fi 链路层可通过确认和重传机制请求或触发重传;
- 如果某个错误侥幸绕过了链路层检错,TCP 等端到端协议仍会通过校验和、序列号和确认机制提供进一步保护。
这体现了网络可靠性的分层设计:链路层在发生错误的附近尽快发现和处理问题,上层协议再从端到端角度兜底。不同层的保护机制并非重复浪费,而是应对不同范围、不同类型的失败。
九、常见误区
1. 校验通过就绝对说明没有差错
不严谨。校验通过表示未检测到错误。校验码越复杂、冗余越充分,漏检概率通常越低,但有限校验字段仍可能存在特定漏检模式。
2. 奇偶校验能检测所有双比特错误
不能。两个比特翻转后,整体奇偶性不变,单一奇偶校验可能漏检。
3. CRC 和校验和只是名字不同
不是。校验和主要利用字级累加关系,CRC 利用生成多项式和模 2 除法构造可整除关系;它们的错误检测特性与典型使用位置不同。
4. CRC 校验失败时一定由链路层重传
不一定。以太网等场景常直接丢弃错误帧,重传可能由 TCP 等更高层完成;无线链路则常在链路层实现局部重传。具体责任由协议设计决定。
5. 能纠正 1 位错误就能同时纠正和检测任意 2 位错误
不一定。标准海明码可以纠正单比特错误,也可以检测双比特错误,但若要可靠地区分单比特与双比特错误并安全纠正,通常需要额外的整体奇偶校验位等扩展设计。
十、总结
差错控制的核心不是消灭噪声,而是在错误不可避免的情况下,用冗余信息发现、定位或恢复错误。奇偶校验用 1 个校验位提供最低成本的奇偶性检查;校验和用字级累加提供较轻量的完整性验证;CRC 用模 2 除法提供强大的链路层检错能力;海明码和其他 FEC 则进一步让接收端能够纠正一定范围内的错误。
理解它们时,可以抓住两条边界:检错只告诉我们"可能错了",纠错才能直接恢复数据;CRC 在常见链路层帧中主要用于检错,发现错误后通常依赖丢弃与重传,而不是自行修复。
当帧可以可靠地判断是否损坏后,下一步就要认识链路层的本地身份标识:MAC 地址。它和 IP 地址分别解决什么问题,又为什么两者缺一不可?
如果这篇文章对你有帮助,欢迎点赞、评论、关注、收藏。你们的支持是我前进的动力!
