海明码の编码过程
海明码不仅能检错,还具有一位纠错能力(告诉你第几位出错)。
比如说,10010 在传输过程中因为噪音影响,接收端收到的是 10000。如果采用海明码,校验码会告诉你:第 4 位错了。
编码过程如下:
1)确定校验码的位数
最终发送的数据 = 原始数据 + 检错码
其中,检错码以一定规律分别插到原始数据中(先不谈)。
不妨假设原始数据有 n 位,校验码有 k 位,则最终数据有 n + k 位。
不难知道,校验码一共有 2 k 2^k 2k 种取值方式(该值告知你第几位出错)。其中需要一种取值方式表示数据正确,由此剩下 2 k − 1 2^k - 1 2k−1 种取值方式分别表示第几位数据出错。
如果要标识第几位出错,则校验码的取值数必须大于总的数据位数,这是理所当然的 (~ ̄▽ ̄)~
所以,有以下不等式: 2 k − 1 ≥ n + k 2^k-1 ≥ n+k 2k−1≥n+k
通过该不等式,我们可以通过知道原始数据的位数,从而确定要填充的校验码位数。
以 10010 为例,n = 5,解出(看出)k 最小为 4。
2)确定校验码的位置
上面说过,检错码是以一定规律分别插到原始数据中的。
这个规律就是逢 2 的整数幂,就插入校验位。
2
0
=
1
,
2
1
=
2
,
2
2
=
4
,
.
.
.
2^0 = 1,2^1 = 2,2^2 = 4,...
20=1,21=2,22=4,...
以 10010 为例,插入校验码后(用 ❤️ 表示校验位 ),
最终发送的数据为: ❤️ ❤️ 1 ❤️ 001 ❤️ 0
3)确定校验码的值
校验码的位置确定了,可填充的是 0 还是 1 呢?显然,这与校验位旁边的原始数据有关(这也正是海明码能够检错纠错的原因)。
校验码 P 1 P 2 P 3 . . . P k − 1 P k P_1P_2P_3...P_{k-1}P_k P1P2P3...Pk−1Pk 的第 i 个校验位的二进制值 P i P_i Pi 的求法如下:
1)将所有数据位的序号用 k 位的二进制数表示;
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
对应的二进制 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
信息位 | D 1 D_1 D1:1 | D 2 D_2 D2:0 | D 3 D_3 D3:0 | D 4 D_4 D4:1 | D 5 D_5 D5:0 | ||||
校验位 | P 1 P_1 P1 | P 2 P_2 P2 | P 3 P_3 P3 | P 4 P_4 P4 |
2)将所有序号的二进制数的第 i 位为 1 的信息位进行异或。以 P 1 P_1 P1 为例(见下表标红的数位)
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
对应的二进制 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
信息位 | D 1 D_1 D1:1 | D 2 D_2 D2:0 | D 3 D_3 D3:0 | D 4 D_4 D4:1 | D 5 D_5 D5:0 | ||||
校验位 | P 1 P_1 P1 | P 2 P_2 P2 | P 3 P_3 P3 | P 8 P_8 P8 |
由此,
P
1
P_1
P1 =
D
1
D_1
D1 ⊕
D
2
D_2
D2 ⊕
D
4
D_4
D4 ⊕
D
5
D_5
D5 = 0
同理, P 2 P_2 P2 = D 1 D_1 D1 ⊕ D 3 D_3 D3 ⊕ D 4 D_4 D4 = 0
P 3 P_3 P3 = D 2 D_2 D2 ⊕ D 3 D_3 D3 ⊕ D 4 D_4 D4 = 1
P 4 P_4 P4 = D 1 D_1 D1 ⊕ D 2 D_2 D2 ⊕ D 4 D_4 D4 ⊕ D 5 D_5 D5 = 0
综上,❤️ ❤️ 1 ❤️ 001 ❤️ 0 = 00 1 1 001 0 0
海明码の校验
假设发送的是 10010,而接收端收到的是 10000。
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
对应的二进制 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
数据位 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
变成了:
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
对应的二进制 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
数据位 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
假设位置为1011的数据由0变成了1,校验过程为:
将所有位置形如1***
, *1**
, **1*
, ***1
的数据位(包括校验位)分别异或。
1***
= 0 ⊕ 0 = 0 【序号8、9分别对应的数据】
*1**
= 1 ⊕ 0 ⊕ 0 ⊕ 0 = 1 【序号4、5、6、7分别对应的数据】
**1*
= 0 ⊕ 1 ⊕ 0 ⊕ 0 = 1
***1
= 0 ⊕ 1 ⊕ 0 ⊕ 0 ⊕ 0 = 1
如果某一组异或值为 1,说明该组中有数据位出错了。
*1**
**1*
***1
的异或都为1,说明出错数据的位置为 0111。
解题技巧
对于串长为 8 的原始数据进行编码,海明码的 4 位校验码分别取以下位置的信息位进行异或即可,可大大提高解题速度。
从左到右)
P 1 P_1 P1:【椅儿是武器】12457
P 2 P_2 P2:【衣裳湿油漆】13467
P 3 P_3 P3:【和尚死吧】2348
P 4 P_4 P4:5678