目录
检测 e 个错误所需的最小距离:d_min >= e + 1
纠正 t 个位错误所需的最小距离:d_min >= 2t + 1
同时检测 e 个错误并纠正 t 个错误所需的最小距离:d_min >= t + e + 1 (其中 e > t)
介绍
本文将详细解析几种在计算机科学和数据通信中至关重要的校验码(Check Code)。校验码的核心目的是检测或纠正数据在存储、传输过程中可能发生的错误。
它们通常通过在原数据的基础上增加一些冗余信息(Redundancy) 来实现。下面我们从简单到复杂,逐一详解其原理和应用。
奇偶校验码
原理讲解
奇偶校验是一种最简单、最基础的错误检测方法。它通过在数据位后增加一个额外的校验位(Parity Bit),使得整个二进制码流中“1”的个数满足预先设定的奇偶性(奇数或偶数)。
-
偶校验 (Even Parity):数据位 + 校验位中,“1”的个数为偶数。
-
奇校验 (Odd Parity):数据位 + 校验位中,“1”的个数为奇数。
核心功能
它的核心功能是检测单个比特( bit)的错误,或者任意奇数个比特的错误。如果错误比特数是偶数,则无法检测(因为“1”的总个数的奇偶性不变)。
关键问题:校验位加在高位还是低位
校验位通常附加在数据的末尾,即最低有效位(LSB - Least Significant Bit)之后
-
硬件实现方便:在串行通信(如UART)中,数据是一位一位地依次传输的。先传输数据位,最后传输校验位,接收方可以在接收过程中实时计算“1”的个数,并在收到校验位后立即进行校验,电路设计非常简单。
-
约定俗成:绝大多数通信协议和系统(如异步串行通信)都将校验位规定在数据帧的末尾。这使得不同设备之间的互联有了统一的标准。
-
逻辑清晰:将原始数据作为一个整体,在其后追加校验位,在编程计算时也非常直观。
需要注意得是,从纯数学角度看,校验位可以放在任何位置(最高位、最低位、甚至中间),只要发送和接收双方事先约定好即可。因为奇偶校验只关心“1”的总个数,而不关心“1”出现的位置。但是,放在数据位的最高位(MSB - Most Significant Bit)之前是极其罕见的,因为这可能会被误解为数据本身的一部分,从而改变数据的值(尤其是数值型数据)。因此,附加在最低位之后是唯一通用且合理的做法。
详细步骤与举例说明
我们通过一个完整的例子来演示奇偶校验的发送方计算和接收方验证过程。
假设场景:
-
我们要传输的原始数据:
1010001
(7位数据) -
双方约定使用偶校验 (Even Parity)
步骤一:发送方计算并附加校验位
-
计算数据位中“1”的个数:
-
数据
1 0 1 0 0 0 1
-
“1”的个数 = 3 (这是一个奇数)
-
-
根据校验规则确定校验位的值:
-
规则是偶校验,要求最终“1”的总数为偶数。
-
当前数据位“1”的个数是3(奇),所以我们需要添加一个校验位
1
,使总数变成 3 + 1 = 4(偶数)。 -
*(如果采用奇校验,当前是3(奇),则校验位应为
0
,使总数保持奇数 3+0=3)*
-
-
形成最终发送的帧:
-
将校验位附加在原始数据的末尾(最低位之后)。
-
最终发送的数据帧为:
1 0 1 0 0 0 1
1
(数据位 + 校验位)
-
步骤二:接收方验证过程
情况一:传输无错误
接收方收到了发送方发来的完整帧:1010001
1
-
计算所有位中“1”的个数(包括数据位和校验位):
1 + 0 + 1 + 0 + 0 + 0 + 1 + 1 = 4
-
判断奇偶性:
4 是 偶数。 -
得出结论:
符合约定的偶校验规则,认为数据传输正确。
情况二:传输发生单比特错误
假设在传输过程中,第3位(从左往右数)由 1
变成了 0
。接收方收到:1 0 **0** 0 0 0 1 1
-
计算所有位中“1”的个数:
1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 = 3
-
判断奇偶性:
3 是 奇数。 -
得出结论:
不符合约定的偶校验规则,认为数据传输过程中发生了错误。
情况三:传输发生双比特错误(奇偶校验的盲点)
假设在传输过程中,第3位和第6位同时出错(1->0
, 0->1
)。接收方收到:1 0 **0** 0 0 **1** 1 1
-
计算所有位中“1”的个数:
1 + 0 + 0 + 0 + 0 + 1 + 1 + 1 = 4
(错误位一减一增,总数不变) -
判断奇偶性:
4 是 偶数。 -
得出结论:
符合偶校验规则,错误无法被检测出来。这就是奇偶校验无法检测偶数个比特错误的原因。
总结
特性 | 说明 |
---|---|
功能 | 检错(只能检测奇数个比特的错误) |
校验位位置 | 几乎总是附加在原始数据的末尾(最低位之后) |
优点 | 原理简单,实现成本极低,只需1位冗余开销 |
缺点 | 1. 只能检错,不能纠错(不知道错误位置) 2. 无法检测偶数个比特的错误 |
应用 | 对可靠性要求不高的场景,如: - 一些低速串行通信(UART) - 简单芯片之间的数据交换 |
海明码
海明码是一种纠错码(Error-Correcting Code, ECC),它不仅能检测错误,还能推导出错误的位置,并还原出发送方实际想要发送的信息,实现纠错。
核心思想
海明码的核心思想是多重奇偶校验。它将多个奇偶校验位巧妙地插入到数据位的不同位置,每个校验位负责校验一组特定的数据位。当错误发生时,通过检查这些校验位的结果,可以直接定位到出错比特的位置。
海明码基本原理
一个非常经典的海明码是(7,4)海明码,(即该海明码共有7个比特位,7个比特位由4个比特的数据位,3个比特的校验位组成)。7个比特的海明码用H7H6H5H4H3H2H1表示,4个比特的数据位用D4D3D2D1表示,3个比特的校验位用P3P2P1表示。接下来以一位出错的情况,来讲解海明码的基本原理,帮助理解记忆其中涉及到的公式。
确定校验位数量
海明码要求满足以下公式,以确定需要多少位校验位(r
):
-
m
: 数据位(Data Bits)的数量 -
r
: 校验位(Parity Bits)的数量 -
m + r
: 最终编码的总长度(Code Word)
例如,要传输4位数据(m=4
):
-
尝试
r=1
: 4+1+1 = 6,而2^1 = 2,不满足公式条件; -
尝试
r=2
: 4+2+1 = 7,而2^2 = 4,不满足公式条件; -
尝试
r=3
: 4+3+1 = 8,而2^3 = 8,满足公式条件; -
尝试
r=4
: 4+4+1 = 9,而2^4 = 16,满足公式条件; -
尝试
r=5
: 4+5+1 = 10,而2^5 = 32,满足公式条件; -
......
需要传输的数据位m是我们设计时确定的,而校验位r则是由公式求出的。
以m=4为例,公式左边,是关于r的线性函数;
而公式右边,是关于r的指数函数
可以得知,满足这样的公式的r有无数个(上述例子中
的正整数均满足条件)
在实际应用中,取满足条件的最小正整数即可(此处取r=3)。
运用此公式求解校验位的数量r的过程大致如此,关于公式的由来将在下面的论述中提到。
数据位和校验位放置位置
4位数据位D4D3D2D1和3位校验位P3P2P1,在7位海明码H7H6H5H4H3H2H1中的放置问题。
H7 | H6 | H5 | H4 | H3 | H2 | H1 |
D4 | D3 | D2 | P3 | D1 | P2 | P1 |
放置校验位
校验位放置在
的位置上
即P1放置在H1位置上;
即P2放置在H2位置上;
即P3放置在H4位置上;
H7 | H6 | H5 | H4 | H3 | H2 | H1 |
P3 | P2 | P1 |
放置数据位
数据位按顺序填充到剩余的空位即可。(这个是收发双方约定一致即可,即使随意放也无太大关系,但为了协议清晰,一般顺序放即可。)
即D4放置在H7位置上;
即D3放置在H6位置