1.码距
-
码距(汉明距离):两个等长编码之间不同位的个数。
-
例如:000 和 001 的码距是1。
-
码距决定了编码的检错和纠错能力。
-
原始无校验的数据码,
最小码距为 1。
-
"两个等长编码之间不同位的个数",指的就是逐位比较两个长度相同的二进制串,统计对应位置上的数字(0或1)不相同的总位数。
奇偶校验的目标 :将任意两个有效编码之间的最小码距 从1增加到2。 这意味着,任何一个有效的奇偶校验码发生单比特错误(1位翻转)后,都会变成一个无效的、不满足奇偶性规则的编码,从而可以被检测出来。
2.奇偶校验
假设我们有一个4位原始数据:1101(其中已有3个"1")。
2.1. 偶校验
- 规则 :使编码中"1"的总个数为偶数。
- 计算 :原始数据
1101中"1"的个数 = 3(奇数)。为了变成偶数,校验位应为1。 - 最终编码(数据位 + 校验位) :
11011 - 验证 :整个5位编码
11011中,"1"的个数为4(偶数),符合规则。
2.2. 奇校验
- 规则 :使编码中"1"的总个数为奇数。
- 计算 :原始数据
1101中"1"的个数 = 3(奇数)。为了保持奇数,校验位应为0。 - 最终编码(数据位 + 校验位) :
11010 - 验证 :整个5位编码
11010中,"1"的个数为3(奇数),符合规则。
好的,我们来用一个完整的例子说明奇偶校验码的工作原理。
偶校验的例子
使用偶校验(使整个编码中"1"的个数为偶数):
原始数据:1 0 1 1(3个"1",是奇数)
- 为了保持偶数,校验位应为
1。 - 发送:
1 0 1 1 1("1"的总数=4,偶数 ✅)
接收方按奇校验检查:
- 若收到
1 0 1 1 1(4个"1")→ 偶数 ✅,无错。 - 若收到
1 1 1 1 1(5个"1")→ 奇数 ❌,检测到错误。 - 若收到
0 0 0 1 1(2个"1")→ 偶数 ✅,错误地判定为无错!。
奇校验的例子
如果采用奇校验(使"1"的总数为奇数):
原始数据:1 0 1 1(3个"1",已是奇数)
- 为了保持奇数,校验位应为
0。 - 发送:
1 0 1 1 0("1"的总数=3,奇数 ✅)
接收方按奇校验检查:
- 若收到
1 0 1 1 0(3个"1")→ 奇数 ✅,无错。 - 若收到
1 0 0 1 0(2个"1")→ 偶数 ❌,检测到错误。 - 若收到
0 0 0 1 0(1个"1")→ 奇数 ✅,错误地判定为无错!。
2.3 奇偶校验码特点总结表
| 特性 | 说明 |
|---|---|
| 增加冗余 | 只增加1位校验位,开销小(n位数据→n+1位传输) |
| 检错能力 | 能100%检测出任意奇数个比特的错误 |
| 无法检测 | 所有偶数个比特的错误 |
| 纠错能力 | 无。只能知道"有错",但不知道哪一位错 |
| 最小码距 | 2(任意两个有效码字至少差2位,原始无校验的数据码最少是1位) |
| 应用场景 | 内存(RAM)校验、串行通信(如UART)、简单数据传输 |
每个比特错误(0变1或1变0)就像按一下开关
-
按奇数下(1, 3, 5...次) → 开关状态一定会改变(从"偶"到"奇")
-
按偶数下(2, 4, 6...次) → 开关状态一定会回到原位(还是"偶")
3.模2除法
✅ 模2除法基本步骤(结合实例说明)
适用场景 :CRC校验、二进制多项式除法等
核心规则 :所有运算在 GF(2) 上进行 → 加减 = 异或(XOR),无进位/借位
📌 步骤总览
-
准备数据
- 被除数(如
1101或1001) - 除数(如
101,必须以1开头)
- 被除数(如
-
初始化窗口
- 取被除数前 ( n ) 位(( n = \text{除数长度} ))作为当前工作区
-
逐位处理(共 ( \text{len(被除数)} - n + 1 ) 步)
- 若当前窗口最高位是 1 :
- 与除数做 XOR
- 商当前位 = 1
- 若当前窗口最高位是 0 :
- 不做 XOR(等价于 XOR 全0,但通常省略)
- 商当前位 = 0
- 左移1位,带入被除数下一位(若还有)
- 若当前窗口最高位是 1 :
-
结束
- 最终剩下的 ( n-1 ) 位即为 余数
- 商可选记录(多数应用如 CRC 不需要)
🧪 示例1:1101 ÷ 101(商无0)
| 步骤 | 当前窗口 | 最高位 | 操作 | 商位 | XOR结果 | 带入下一位 |
|---|---|---|---|---|---|---|
| 1 | 110 |
1 | XOR 101 |
1 | 011 |
带入 1 → 0111 |
| 2 | 111 |
1 | XOR 101 |
1 | 010 |
无 |
✅ 商 = 11,余数 = 10
💡 两次窗口最高位都是1 → 商全是1,没有0
💡 模2除法的"窗口"是动态对齐到当前最高位的1,不是固定从左到右逐位判断!
- 你可能误以为中间出现的 011 中的"0"需要"跳过",但实际上:
- 那个 0 是XOR结果的一部分,不是"新的被除数起始位"
- 我们不会对每一位单独判断是否跳过,而是:
- 每次看当前3位窗口的最高位是否为1
- 在第二步,窗口是 111(不是 011),所以不需要跳过,直接XOR,商写1
🧪 示例2:1001 ÷ 101(商有0)
| 步骤 | 当前窗口 | 最高位 | 操作 | 商位 | XOR结果 | 带入下一位 |
|---|---|---|---|---|---|---|
| 1 | 100 |
1 | XOR 101 |
1 | 001 |
带入 1 → 0011 |
| 2 | 011 |
0 | 不XOR | 0 | 011 |
无 |
✅ 商 = 10,余数 = 11
💡 第二步窗口是
011,最高位为0 → 商写0,跳过XOR
🔑 关键要点总结
| 问题 | 正确认知 |
|---|---|
| "跳过"是什么意思? | 当前窗口最高位为0 → 商0,不执行XOR,直接移位 |
| 商是否存在? | 存在!每一步都有一位商(1 或 0),但 CRC 中通常忽略 |
| 余数长度? | 总是 = 除数长度 − 1(如除数3位 → 余数2位) |
| 是否逐位判断? | 否!是按 与除数等长的窗口 判断最高位 |
| 前导0怎么处理? | 窗口包含前导0,但只看该窗口的最高位决定是否XOR |
📝 一句话口诀(便于记忆)
"对齐除数看头位,是1就XOR商写1,是0跳过商写0,移位带入继续算。"
4.普通算术除法
🔥 经典借位场景:100 ÷ 3
我们一步步手算,并高亮借位发生的位置。
第一步:列竖式
??
------
3 ) 1 0 0
-
3 不能整除 1(百位),所以看前两位:10
-
10 ÷ 3 = 3(因为 3×3=9 ≤ 10)
-
商的第一位是 3,写在十位上
3 ------3 ) 1 0 0
- 9 ← 3 × 3 = 9
-----
第二步:做减法 10 − 9
1 0
− 9
-------
- 个位:0 − 9 → 不够减!
- 向十位借1
- 十位的1变成0,个位得到10
- 计算:10 − 9 = 1
✅ 这里发生了借位!
结果是 1 ,然后把被除数的下一位 0 移下来,变成 10
3
------
3 ) 1 0 0
- 9
-----
1 0 ← 余1,带下0 → 10
第三步:10 ÷ 3 = 3(3×3=9)
3 3
------
3 ) 1 0 0
- 9
-----
1 0
- 9
-----
1 ← 余数
再做一次减法:10 − 9
→ 又一次:0 − 9 不够,向十位借1 → 再次借位!
✅ 完整过程(标出借位)
3 3
------
3 ) 1 0 0
- 9 ← 3×3
-----
→ ¹0 ← 十位1借给个位,自己变0,个位变成10
1 0 ← 实际是 (10−9)=1,带下0 → 10
- 9
-----
→ ¹0 ← 再次借位!
1 ← 余数
💡 每次计算
10 − 9时,个位0不够减9,必须向十位借1 ,这就是带借位。
📌 关键点总结
| 步骤 | 发生了什么 | 是否借位 |
|---|---|---|
| 10 − 9 | 个位 0 < 9 → 向十位借1 | ✅ 是 |
| 10 − 9(第二次) | 同样,个位0 < 9 → 借1 | ✅ 是 |
在十进制中,借1当10,所以 0 借位后变成 10,就能减了。
✅ 最终结果
- 商:33
- 余数:1
- 验证:( 3 \times 33 + 1 = 99 + 1 = 100 ) ✅
🔁 对比记忆
-
普通算术除法:
- 减法要借位(如 0 − 9 → 借1变10 − 9 = 1)
- 是我们小学学的"标准除法"
-
模2除法(用于CRC):
- 减法 = 异或(XOR)
0 − 1 = 1(因为 0 ⊕ 1 = 1),永远不需要借位
💬 一句话记住
"普通除法中的借位,就是你算 100 ÷ 3 时,每次 10 减 9 都要从十位'借1当10'的那个动作。"
5.CRC
循环冗余校验码(Cyclic Redundancy Check,CRC)
6.海明码
6.1 校验码
已知原始信息数据为 1011,海明码校验码
1. 确定校验位个数
设原始数据位数 ( m = 4 )(即 1011)。
海明码要求满足 ( 2^r \ge m + r + 1 ) 来确定校验位个数 ( r )。
- ( r = 2 ) 时:( 4 + 2 + 1 = 7),(2^2 = 4) 不够。
- ( r = 3 ) 时:( 4 + 3 + 1 = 8),(2^3 = 8) 刚好满足。
所以 校验位 ( r = 3 ),总位数 ( n = m + r = 7 )。
2. 确定校验位的位置
校验位 ( P_1, P_2, P_4 ) 放在 ( 2^{i-1} ) 的位置(即位置 1、2、4,从 1 开始数位置)。
位置编号与对应位的关系(P 表示校验位,D 表示数据位):
| 位置 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|---|---|---|---|---|---|---|---|
| 位 | D4 | D3 | D2 | P3 | D1 | P2 | P1 |
原始数据 1011 按顺序 ( D_4 D_3 D_2 D_1 ) 填入 ( D4, D3, D2, D1 ):
- ( D4 = 1 )
- ( D3 = 0 )
- ( D2 = 1 )
- ( D1 = 1 )
暂时校验位未知(记为 P1, P2, P3),我们得到:
| 位置 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|---|---|---|---|---|---|---|---|
| 位 | 1 | 0 | 1 | P3 | 1 | P2 | P1 |
| 位置 | 二进制(从右数位 1,2,4 对应权值 1,2,4) | 存放的位 |
|---|---|---|
| 1 | 001 | P1 |
| 2 | 010 | P2 |
| 3 | 011 | D1=1 |
| 4 | 100 | P3 |
| 5 | 101 | D2=1 |
| 6 | 110 | D3=0 |
| 7 | 111 | D4=1 |
3. 确定每个校验位的奇偶校验组(偶校验)
P1(位置 1) 校验的位:位置 1、3、5、7 的二进制 最低位为 1 。
即:1(1), 3(3=011), 5(5=101), 7(7=111) → 对应位 P1, D1, D2, D4。
P_1 \\oplus D1 \\oplus D2 \\oplus D4 = 0
P_1 \\oplus 1 \\oplus 1 \\oplus 1 = 0
P_1 \\oplus 1 = 0 \\quad \\Rightarrow \\quad P_1 = 1
(因为 ( 1 \oplus 1 = 0 ))
P2(位置 2) 校验的位:位置 2、3、6、7 的二进制 次低位为 1 。
即:2(010), 3(011), 6(110), 7(111) → 对应位 P2, D1, D3, D4。
P_2 \\oplus D1 \\oplus D3 \\oplus D4 = 0
P_2 \\oplus 1 \\oplus 0 \\oplus 1 = 0
P_2 \\oplus 0 = 0 \\quad \\Rightarrow \\quad P_2 = 0
P3(位置 4) 校验的位:位置 4、5、6、7 的二进制 第三位为 1 。
即:4(100), 5(101), 6(110), 7(111) → 对应位 P3, D2, D3, D4。
P_3 \\oplus D2 \\oplus D3 \\oplus D4 = 0
P_3 \\oplus 1 \\oplus 0 \\oplus 1 = 0
P_3 \\oplus 0 = 0 \\quad \\Rightarrow \\quad P_3 = 0
4. 填入校验位得到完整海明码
P1=1,P2=0,P3=0。
位置:
1 → 1
2 → 0
3 → D1=1
4 → P3=0
5 → D2=1
6 → D3=0
7 → D4=1
得到:位置 7~1 为 1 0 1 0 1 0 1(注意通常书写顺序按位置 1 在最右)
从高到低(位置 7 到 1)的二进制是:1010101。
5. 最终答案
原始数据 1011,海明校验码(7 位)为:
\\boxed{1010101}
其中校验位是 ( P_1 = 1, P_2 = 0, P_3 = 0 ),放在总码的位置 1、2、4。
我们具体看一下这一步的详细推导。
海明码的偶校验 是一种保证特定校验组内"1"的个数为偶数的机制。
具体来说:
6.2 海明码中的偶校验和奇校验
1. 偶校验(Even Parity)
对于一组二进制位,偶校验位设置成 0 或 1 ,使得这组数据位加校验位中 "1"的总数 为偶数。
例如:
- 数据
101→ "1"的个数 = 2(偶数),则校验位 = 0,保持偶数。 - 数据
111→ "1"的个数 = 3(奇数),则校验位 = 1,使总数变成 4(偶数)。
校验方程:
P \\oplus D_1 \\oplus D_2 \\oplus \\dots \\oplus D_k = 0
(即所有位异或结果为 0)
2. 海明码中的偶校验应用
在海明码中,每个校验位负责一组不同的数据位。分组规则是根据位置的二进制编号来划分的。
对于长度为 ( n ) 的海明码(( n = m + r )),位置从 1 到 ( n ) 编号,校验位放在 ( 2^{i-1} ) 的位置(即 1、2、4、8...)。
校验位 ( P_k )(在位置 ( 2^{k-1} ))负责校验所有位置编号二进制表示中,第 ( k ) 位(从右数,最低位是第 1 位)是 1 的那些位置。
例子(7 位海明码,r=3)
- ( P_1 )(位置 1):二进制最低位是 1 的位置 → 1, 3, 5, 7
- ( P_2 )(位置 2):二进制第二位是 1 的位置 → 2, 3, 6, 7
- ( P_4 )(位置 4):二进制第三位是 1 的位置 → 4, 5, 6, 7
对每个校验组分别进行偶校验,得到一个方程,解出该校验位的值。
3. 偶校验的作用
在发送端,校验位按偶校验规则计算填入。
在接收端,重新计算每个校验方程,如果全部为 0,则无错;如果有方程不为 0,将这些方程的校验位位置值组合成一个二进制数,就指示出错的位置。
这是因为偶校验组重叠覆盖了每一个位,任何单个位置错误都会影响一组特定的校验方程,从而唯一确定出错位。
4. 与奇校验的区别
- 偶校验:组内异或结果 = 0
- 奇校验:组内异或结果 = 1
海明码常用偶校验(教材标准做法),但奇校验原理类似,只是方程右边为 1。
所以简单说:
海明码的偶校验 = 将数据位和校验位按特定规则分组,每组内通过设置校验位使得"1"的个数为偶数,以便检错与纠错。
判断数据位由哪些校验码校验,规则如下:
6.3.数据位由哪些校验码校验
在海明码中,每一个数据位的位置编号(从 1 开始数) 的二进制形式中,如果某一位是 1,那么它就受到对应权值的校验位的校验。
校验位的位置是 ( 2^{k-1} ):
- 校验位 ( P_1 ) 在位置 ( 1 = 2^{0} )(二进制 001) → 负责最低位为 1 的所有位置
- 校验位 ( P_2 ) 在位置 ( 2 = 2^{1} )(二进制 010) → 负责第二位为 1 的所有位置
- 校验位 ( P_3 ) 在位置 ( 4 = 2^{2} )(二进制 100) → 负责第三位为 1 的所有位置
......依此类推。
1. 判断方法
步骤 1:给数据位位置编号(整个海明码的位置)
假设我们有一个 7 位海明码(4 数据位 + 3 校验位),位置从 1 到 7:
| 位置 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|---|---|---|---|---|---|---|---|
| 存放 | D4 | D3 | D2 | P3 | D1 | P2 | P1 |
数据位 ( D_1 ) 在位置 3,( D_2 ) 在位置 5,( D_3 ) 在位置 6,( D_4 ) 在位置 7。
步骤 2:将数据位的位置编号转换成二进制(用 r 位)
这里 r=3,二进制用 3 位(因为校验位位置是 1,2,4,对应二进制位 1,2,3 从右数)。
-
( D_1 ) 位置 3 → 二进制 011
- 最低位是 1 → 受 P1 校验
- 第二位是 1 → 受 P2 校验
- 第三位是 0 → 不受 P3 校验
所以 ( D_1 ) 由 P1 和 P2 校验。
-
( D_2 ) 位置 5 → 二进制 101
- 最低位是 1 → 受 P1 校验
- 第二位是 0 → 不受 P2 校验
- 第三位是 1 → 受 P3 校验
所以 ( D_2 ) 由 P1 和 P3 校验。
-
( D_3 ) 位置 6 → 二进制 110
- 最低位是 0 → 不受 P1 校验
- 第二位是 1 → 受 P2 校验
- 第三位是 1 → 受 P3 校验
所以 ( D_3 ) 由 P2 和 P3 校验。
-
( D_4 ) 位置 7 → 二进制 111
- 最低位是 1 → 受 P1 校验
- 第二位是 1 → 受 P2 校验
- 第三位是 1 → 受 P3 校验
所以 ( D_4 ) 由 P1、P2、P3 全部校验。
2. 总结公式
对于位置编号 ( pos )(二进制表示),如果二进制从右数第 ( k ) 位(k 从 1 开始)是 1,则该校验位 ( P_k )(位置 ( 2^{k-1} ))会校验该数据位。
更简单的记忆法:
将数据位的位置编号分解成 2 的幂次和,幂次对应的校验位就是它受的校验。
例:
- ( 3 = 1 + 2 ) → P1、P2
- ( 5 = 1 + 4 ) → P1、P3
- ( 6 = 2 + 4 ) → P2、P3
- ( 7 = 1 + 2 + 4 ) → P1、P2、P3
3. 反过来:校验位校验哪些位置?
2^{i} i=0,i=1,i=2... 1(001),2(010),4(100),8(1000),16(10000)
校验位 P1(位置 1)校验所有二进制最低位为 1 的位置。
校验位 P2(位置 2)校验所有二进制第二位为 1 的位置。
校验位 P4(位置 4)校验所有二进制第三位为 1 的位置。
校验位 P4(位置 8)校验所有二进制第四位为 1 的位置。
这样就可以从数据位位置反推出由哪些校验位校验,也可以从校验位知道它覆盖了哪些数据位。
6.4.海明码的检错和纠错原理
海明码的检错和纠错原理 基于多个奇偶校验位(偶校验)对数据位进行重叠分组,使得任何单个比特错误会影响一组特定的校验方程,从而唯一确定错误位置。
1.核心思想
- 冗余位(校验位):插入 ( r ) 个校验位到数据位中,总长度 ( n = m + r )。
- 分组校验:每个校验位负责一组特定的数据位(包括其他某些校验位)。
- 重叠覆盖:每一个数据位至少属于两个不同的校验组。
- 定位错误 :单个比特出错会破坏它所在的所有校验组的偶校验条件,这些被破坏的校验组的编号组合起来就唯一对应出错的位置。
2.编码过程(复习)
假设数据位 ( D_4 D_3 D_2 D_1 = 1011 ),求海明码(7,4):
-
确定校验位个数 ( r ),满足 ( 2^r \ge m + r + 1 )(这里是 3)。
-
校验位放在位置 ( 1, 2, 4 )(即 ( 2^{k-1} ))。
-
位置分配:
位置:7 6 5 4 3 2 1
存放:D4 D3 D2 P3 D1 P2 P1
填入数据位:D4=1, D3=0, D2=1, D1=1。
-
计算校验位(偶校验):
- P1(校验位置 1,3,5,7):P1 ⊕ D1 ⊕ D2 ⊕ D4 = 0 → P1=1
- P2(校验位置 2,3,6,7):P2 ⊕ D1 ⊕ D3 ⊕ D4 = 0 → P2=0
- P3(校验位置 4,5,6,7):P3 ⊕ D2 ⊕ D3 ⊕ D4 = 0 → P3=0
得到海明码:位置 7~1 → 101 0 1 0 1 即 1010101。
3.检错与纠错过程(接收端)
1. 重新计算校验方程
收到一个 7 位码字,按同样分组计算偶校验结果,得到校验子(Syndrome) ( S_3 S_2 S_1 ):
\\begin{cases} S_1 = P_1 \\oplus D_1 \\oplus D_2 \\oplus D_4 \\quad (\\text{应为 0,若为 1 则本组有错}) \\ S_2 = P_2 \\oplus D_1 \\oplus D_3 \\oplus D_4 \\ S_3 = P_3 \\oplus D_2 \\oplus D_3 \\oplus D_4 \\end{cases}
注意:这里的 ( P_1, D_1 ) 等是从接收到的码字中取对应位置的值。
2. 校验子含义
- 如果 ( S_3 S_2 S_1 = 000 ) → 无错(或不可检测的多错,海明码只能保证检测并纠正 1 位错)。
- 如果 ( S_3 S_2 S_1 \neq 000 ),则它是一个二进制数,直接指出出错的位置编号。
为什么?
因为每个位置的编号二进制形式对应它会影响哪些校验组(S1 对应最低位,S2 对应第二位,S3 对应第三位)。
例子:
- 假设 D2(位置 5)出错:
位置 5 二进制 101 → 影响 P1(最低位)和 P3(第三位),不影响 P2。
所以:
( S_1 = 1 )(P1 组偶校验破坏)
( S_2 = 0 )
( S_3 = 1 )
校验子 ( S_3 S_2 S_1 = 101 )(二进制)→ 十进制 5,正好是出错位置。
3. 纠错
得到校验子 ( S = (S_3 S_2 S_1)_2 ),转十进制得到出错位置。
将该位置的比特取反(0→1 或 1→0),即完成纠正。
4. 举例验证
发:1010101
收:假设位置 5 由 1 错成 0,收到 1000101。
重新计算校验子:
位置 7(D4)=1, 6(D3)=0, 5(D2)=0, 4(P3)=0, 3(D1)=1, 2(P2)=0, 1(P1)=1。
- ( S_1 = P1 ⊕ D1 ⊕ D2 ⊕ D4 = 1 ⊕ 1 ⊕ 0 ⊕ 1 = 1 ⊕ 1 = 0 ⊕ 1 = 1 )
(仔细算:1⊕1=0, 0⊕0=0, 0⊕1=1 → 最终 S1=1)
其实更清楚列式:
P1 组包含位置 1(P1=1), 3(D1=1), 5(D2=0), 7(D4=1)
1 的个数:1(P1)是1, 3(D1)是1, 5(D2)是0, 7(D4)是1 → 1 的个数 = 3(奇数)→ 偶校验破坏 → S1=1。
-
( S_2 = P2 ⊕ D1 ⊕ D3 ⊕ D4 )
位置 2(P2=0), 3(D1=1), 6(D3=0), 7(D4=1)
1 的个数:D1=1, D4=1 → 两个 1(偶数),P2=0 不影响,所以总共 1 的个数=2(偶数)→ 偶校验满足 → S2=0。
-
( S_3 = P3 ⊕ D2 ⊕ D3 ⊕ D4 )
位置 4(P3=0), 5(D2=0), 6(D3=0), 7(D4=1)
1 的个数:1(奇数)→ S3=1。
所以 ( S_3 S_2 S_1 = 101 ) → 十进制 5 → 位置 5 错。
纠正:位置 5 的 0 改为 1 → 恢复为 1010101。
4.检错能力
- 可纠正 1 位错(因为校验子 000 表示无错,其它 ( 2^r - 1 ) 种非零值对应 n 位中的某一位错,这里 ( n \le 2^r - 1 ))。
- 可检测 2 位错(校验子非零,但无法唯一确定是哪两位错,因为校验子模式与错误图样不再是一一对应,只能发现错误但不能纠正)。
- 不能可靠检测 ≥3 位错(可能校验子又变回 000 而漏检)。