Hamming Code - 从集合的角度理解海明码(轻松理解海明码的设计思想)
一、 我们先来回顾一下海明码的计算过程:
①
、
确
定
校
验
码
位
数
r
①、确定校验码位数\ r
①、确定校验码位数 r
2
r
≥
k
+
r
+
1
2^r \ge k + r + 1
2r≥k+r+1
其
中
,
r
为
冗
余
位
长
度
,
k
为
信
息
位
长
度
。
\qquad 其中,r 为冗余位长度,k 为信息位长度。
其中,r为冗余位长度,k为信息位长度。
② 、 确 定 校 验 码 和 数 据 的 位 置 ②、确定校验码和数据的位置 ②、确定校验码和数据的位置
校
验
码
P
1
,
P
i
,
.
.
.
,
P
r
放
在
2
的
幂
次
的
位
置
,
举
例
:
\qquad校验码P_1,P_i,...,P_r 放在 2 的幂次的位置,举例:
校验码P1,Pi,...,Pr放在2的幂次的位置,举例:
③
、
求
出
校
验
码
的
值
③、求出校验码的值
③、求出校验码的值
首先,写出数据位的位数的二进制表示。如
P
1
P_1
P1 是数据的第一位,1 的位表示为
0001
0001
0001。
然后,根据每一位校验位 “1” 所在的位置(因为校验位都放在 2 的幂次的位置,所以校验位位置的二进制表示中都只有 1 个 “1”),确定它们校验的数据是哪几位。如 P 2 P_2 P2 在第 2 位,其二进制表示(0010)中,“1” 处在倒数第二位,所以,所有二进制表示中,倒数第二位为 “1” 的位置的数据都是它校验的数据,即:第 3(00 1 1)位 D 1 D_1 D1、第 6(01 1 0)位 D 3 D_3 D3、第 7(01 1 1)位 D 4 D_4 D4、第 10(10 1 0)位 D 6 D_6 D6。
最后,计算方程:
P
2
⊕
D
1
⊕
D
3
⊕
D
4
⊕
D
6
=
0
⟺
P
2
⊕
1
⊕
1
⊕
1
⊕
1
=
0
P_2\oplus D_1 \oplus D_3\oplus D_4 \oplus D_{6}=0 \\ \space \\ \Longleftrightarrow P_2\oplus 1 \oplus 1\oplus 1 \oplus 1=0
P2⊕D1⊕D3⊕D4⊕D6=0 ⟺P2⊕1⊕1⊕1⊕1=0
得到
P
2
=
0
P_2=0
P2=0
同理可得 P 1 = 0 、 P 3 = 0 、 P 4 = 1 P_1=0、P_3=0、P_4=1 P1=0、P3=0、P4=1,海明码为 00 1 0 011 1 01。
④ 、 检 错 并 纠 错 ④、检错并纠错 ④、检错并纠错
假设接收到的数据为 00 1 0 111 1 01
用所有校验码进行检测:
P
4
⊕
D
5
⊕
D
6
=
1
⊕
0
⊕
1
=
0
P
3
⊕
D
2
⊕
D
3
⊕
D
4
=
0
⊕
1
⊕
1
⊕
1
=
1
P
2
⊕
D
1
⊕
D
3
⊕
D
4
⊕
D
6
=
0
⊕
1
⊕
1
⊕
1
⊕
1
=
0
P
1
⊕
D
1
⊕
D
2
⊕
D
4
⊕
D
5
=
0
⊕
1
⊕
1
⊕
1
⊕
0
=
1
P_4\oplus D_5\oplus D_6 =1\oplus 0\oplus 1=0\\P_3\oplus D_2\oplus D_3\oplus D_4 =0\oplus 1\oplus 1\oplus 1=1\\P_2\oplus D_1\oplus D_3\oplus D_4\oplus D_6 =0\oplus 1\oplus 1\oplus 1\oplus 1=0\\P_1\oplus D_1\oplus D_2\oplus D_4\oplus D_5 =0\oplus 1\oplus 1\oplus 1\oplus 0=1
P4⊕D5⊕D6=1⊕0⊕1=0P3⊕D2⊕D3⊕D4=0⊕1⊕1⊕1=1P2⊕D1⊕D3⊕D4⊕D6=0⊕1⊕1⊕1⊕1=0P1⊕D1⊕D2⊕D4⊕D5=0⊕1⊕1⊕1⊕0=1
得到的结果序列为:
(
0101
)
2
=
5
(0101)_2=5
(0101)2=5,表明出错位是第 5 位
D
2
D_2
D2。
二、 下面,我们来思考为什么海明码最后可以恰巧表示出错的位置
考虑下面三个问题:
-
如何理解公式 2 r ≥ k + r + 1 2^r\ge k+r+1 2r≥k+r+1 ?
我们可以把 r r r 位校验码看成是一种状态压缩的表示形式。它表示了 2 r 2^r 2r 不同的状态,包括: k + r k+r k+r 位的错误位置信息、全 0 时表示无差错的状态(最后那个 + 1)。 -
为什么要在 2 的幂次的位置放置校验位?
因为 2 0 、 2 1 、 . . . 、 2 r − 1 2^0、2^1、...、2^{r-1} 20、21、...、2r−1,这些数进行任意的组合,可以表达出 r r r 位二进制数的任意值,也就能够校验一个长度不超过 2 r 2^r 2r 的二进制数的任意比特。因此, r r r 位校验位就能够校验海明码的每一比特的值。 -
为什么要令校验码和其对应校验的数据位的校验和为零?(第3 步)
我们反过来思考:最后校验时,结果为 1,有什么含义?
因为我们计算校验码时,令异或和结果为 0;最后校验时,结果为 1,说明出现了错误(因为发送之前我们的异或和为 0 呀)。而错误的位置,就是校验码 P i ( 00...1 . . . 00 ⏟ i − 1 ) P_i(00...1\underbrace{...00}_{i-1}) Pi(00...1i−1 ...00) 对应的那几位数据位(位置的二进制表示中,倒数第 i i i 位为 “1” 的数据位)其中的一个。然后几个校验位的组合,就确定了错误的位置。
拿上面的例子举例:-
P 4 ⊕ D 5 ⊕ D 6 = 1 ⊕ 0 ⊕ 1 = 0 P_4\oplus D_5\oplus D_6 =1\oplus 0\oplus 1=0 P4⊕D5⊕D6=1⊕0⊕1=0,说明 P 4 P_4 P4 对应的数据位 E 4 = { D 5 、 D 6 } E_4=\{D_5、D_6\} E4={D5、D6} 没有出错
-
P 3 ⊕ D 2 ⊕ D 3 ⊕ D 4 = 0 ⊕ 1 ⊕ 1 ⊕ 1 = 1 P_3\oplus D_2\oplus D_3\oplus D_4 =0\oplus 1\oplus 1\oplus 1=1 P3⊕D2⊕D3⊕D4=0⊕1⊕1⊕1=1,说明错误位置在 P 3 P_3 P3 对应的数据位 E 3 = { D 2 , D 3 , D 4 } E_3=\{D_2,D_3,D_4\} E3={D2,D3,D4} 中。
-
P 2 ⊕ D 1 ⊕ D 3 ⊕ D 4 ⊕ D 6 = 0 ⊕ 1 ⊕ 1 ⊕ 1 ⊕ 1 = 0 P_2\oplus D_1\oplus D_3\oplus D_4\oplus D_6 =0\oplus 1\oplus 1\oplus 1\oplus 1=0 P2⊕D1⊕D3⊕D4⊕D6=0⊕1⊕1⊕1⊕1=0,说明 E 2 = { D 1 、 D 3 、 D 4 、 D 6 } E_2=\{D_1、D_3、D_4、D_6\} E2={D1、D3、D4、D6} 中的位置没有出错。
-
P 1 ⊕ D 1 ⊕ D 2 ⊕ D 4 ⊕ D 5 = 0 ⊕ 1 ⊕ 1 ⊕ 1 ⊕ 0 = 1 P_1\oplus D_1\oplus D_2\oplus D_4\oplus D_5 =0\oplus 1\oplus 1\oplus 1\oplus 0=1 P1⊕D1⊕D2⊕D4⊕D5=0⊕1⊕1⊕1⊕0=1,说明错误位置在 E 1 = { D 1 , D 2 , D 4 , D 5 } E_1=\{D_1,D_2,D_4,D_5\} E1={D1,D2,D4,D5} 中。
然后我们计算:
( E 3 ⋂ E 1 ) − ( E 4 ⋃ E 2 ) = { D 2 , D 4 } − { D 1 , D 3 , D 4 , D 5 , D 6 } = { D 2 } (E_3\bigcap E_1)-(E_4\bigcup E_2)=\{D_2,D_4\}-\{D_1,D_3,D_4,D_5,D_6\}=\{D_2\} (E3⋂E1)−(E4⋃E2)={D2,D4}−{D1,D3,D4,D5,D6}={D2}
得到,出错的数据位是 D 2 D_2 D2。 -
到这里,海明码的设计思路就很清晰了。