海明码
海明码基本思想是分组偶校验,由信息位(n)和校验位(k)组成,海明码的校验位计算公式:2^k >= n+k+1
2^k表示:k个校验位对应2^k种状态n + k + 1表示:n + k代表任何一位都可能出错,1代表一种正确的状态
所有的幂次位都是校验位,代表一组的偶校验值。
确定海明码位数:信息位(n) + 校验位(k) :通过信息位算出校验位:
2^k >= n+k+1校验位的位置编号:
2^(k-1)将信息位填入剩余位置
把信息位的位置编号用二进制数表示
二进制数的每一位对应校验位.将二进制数是
1的进行组合用异或运算算出校验位,得到海明码
对海明码整体进行偶校验得到最终的海明码
假设数据为10101011
求校验位
k,代入公式2^k >= n + k + 1。校验位算出是k=4位,记为:P1~P4海明位
h:由信息位和校验位组成:8 + 4 = 12,记为H1~H12填入数据位:校验位所在的位置是
2^(k-1),P1~P4对应H1,H2,H4,H8,信息位填入剩下的空位:
| H12 | H11 | H10 | H9 | H8 | H7 | H6 | H5 | H4 | H3 | H2 | H1 |
| D8 | D7 | D6 | D5 | P4 | D4 | D3 | D2 | P3 | D1 | P2 | P1 |
| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
- 计算剩余的
P1~P4的值。求校验位需要先知道信息位所在位置的二进制(k位,对应校验位)
信息位所在位置:
H3/H5/H6/H7/H9/H10/H11/H12信息位的最后一位为
P1,最后第二位为P2,以此类推
| 数据位位置码 | P4 | P3 | P2 | P1 |
H30011 |
0 | 0 | 1 | 1 |
H50101 |
0 | 1 | 0 | 1 |
H60110 |
0 | 1 | 1 | 0 |
H70111 |
0 | 1 | 1 | 1 |
H91001 |
1 | 0 | 0 | 1 |
H101010 |
1 | 0 | 1 | 0 |
H111011 |
1 | 0 | 1 | 1 |
H121100 |
1 | 1 | 0 | 0 |
校验位对应各信息位二进制数为 1 的组合:
P1对应的信息位H3/H5/H7/H9/H11P2对应的信息位H3/H6/H7/H10/H11P3对应的信息位H5/H6/H7/H12P4对应的信息位H9/H10/H11/H12
- 将各信息位的值进行异或运算,求得校验位的值:
- P4 = H9/H10/H11/H12 → D5⊕D6⊕D7⊕D8 → 0⊕1⊕0⊕1 → 0
- P3 = H5/H6/H7/H12 → D2⊕D3⊕D4⊕D8 → 1⊕0⊕1⊕1 → 1
- P2 = H3/H6/H7/H10/H11 → D1⊕D3⊕D4⊕D6⊕D7 → 1⊕0⊕1⊕1⊕0 → 1
- P1 = H3/H5/H7/H9/H11 → D1⊕D2⊕D4⊕D5⊕D7 → 1⊕1⊕1⊕0⊕0 → 1
P1P2P3P4=1110填入:
| H12 | H11 | H10 | H9 | H8 | H7 | H6 | H5 | H4 | H3 | H2 | H1 |
| D8 | D7 | D6 | D5 | P4 | D4 | D3 | D2 | P3 | D1 | P2 | P1 |
| 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
最终得到的海明码为:101001011111
S1:P1⊕D1⊕D2⊕D4⊕D5⊕D7 -> 1⊕1⊕1⊕1⊕0⊕0 -> 0
S2:P2⊕D1⊕D3⊕D4⊕D6⊕D7 -> 1⊕1⊕0⊕1⊕1⊕0 -> 0
S3:P3⊕D2⊕D3⊕D4⊕D8 -> 1⊕1⊕0⊕1⊕1 -> 0
S4:P4⊕D5⊕D6⊕D7⊕D8 -> 0⊕0⊕1⊕0⊕1 -> 0
海明码纠错的方式是:各校验位用偶校验进行校验
S4S3S2S1 = 0000 且整体偶检验成功:无错误
S4S3S2S1 ≠ 0000 且整体偶检验失败:一位错误,纠正即可
S4S3S2S1 ≠ 0000 且整体偶检验成功:两位错误,需重传
一位出错
| H12 | H11 | H10 | H9 | H8 | H7 | H6 | H5 | H4 | H3 | H2 | H1 | |
| D8 | D7 | D6 | D5 | P4 | D4 | D3 | D2 | P3 | D1 | P2 | P1 | |
| 正确 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| H2错 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
代入校验方程:
S1:P1⊕D1⊕D2⊕D4⊕D5⊕D7 -> 1⊕1⊕1⊕1⊕0⊕0 -> 0
S2:P2⊕D1⊕D3⊕D4⊕D6⊕D7 -> 0⊕1⊕0⊕1⊕1⊕0 -> 1
S3:P3⊕D2⊕D3⊕D4⊕D8 -> 1⊕1⊕0⊕1⊕1 -> 0
S4:P4⊕D5⊕D6⊕D7⊕D8 -> 0⊕0⊕1⊕0⊕1 -> 0
得到错误位S4S3S2S1:0010,转为十进制为 2,也就是说 H2 处错了。
例2:
| H12 | H11 | H10 | H9 | H8 | H7 | H6 | H5 | H4 | H3 | H2 | H1 | |
| D8 | D7 | D6 | D5 | P4 | D4 | D3 | D2 | P3 | D1 | P2 | P1 | |
| 正确 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| H11 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
代入校验方程:
S1:P1⊕D1⊕D2⊕D4⊕D5⊕D7->1⊕1⊕1⊕1⊕0⊕1->1S2:P2⊕D1⊕D3⊕D4⊕D6⊕D7->1⊕1⊕0⊕1⊕1⊕1->1S3:P3⊕D2⊕D3⊕D4⊕D8->1⊕1⊕0⊕1⊕1->0S4:P4⊕D5⊕D6⊕D7⊕D8->0⊕0⊕1⊕1⊕1->1
得到错误位S4S3S2S1:1011,转为十进制为 11,也就是说 H11 处错了。
S4S3S2S1 指明了出错位在哪里
两位出错
| H12 | H11 | H10 | H9 | H8 | H7 | H6 | H5 | H4 | H3 | H2 | H1 | |
| D8 | D7 | D6 | D5 | P4 | D4 | D3 | D2 | P3 | D1 | P2 | P1 | |
| 正确 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| H2、H9 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
代入校验方程:
S1:P1⊕D1⊕D2⊕D4⊕D5⊕D7 -> 0⊕1⊕1⊕1⊕1⊕1 -> 1
S2:P2⊕D1⊕D3⊕D4⊕D6⊕D7 -> 1⊕1⊕0⊕1⊕1⊕1 -> 1
S3:P3⊕D2⊕D3⊕D4⊕D8 -> 1⊕1⊕0⊕1⊕1 -> 0
S4:P4⊕D5⊕D6⊕D7⊕D8 -> 1⊕1⊕1⊕1⊕1 -> 1
得到错误位S4S3S2S1:1011,转为十进制为 11,是否说明了 H11 位出错了呢?
所以海明码只有一位的纠错能力。
全校验位
为了保证海明码的校验能力,引入全校验位,对海明码整体进行偶校验
由于要进行偶校验,上面的海明码有八个 1,所以最高位 H13 是 0:
| H13 | H12 | H11 | H10 | H9 | H8 | H7 | H6 | H5 | H4 | H3 | H2 | H1 |
| P5 | D8 | D7 | D6 | D5 | P4 | D4 | D3 | D2 | P3 | D1 | P2 | P1 |
| 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
最终的海明码为:0101001011111
同一编码中,任意两个合法编码之间不同二进制位数的最小值
0011 与 0001 的码距为 1,一位错误时无法识别
0000、0011、0101、0110、1001、1010、1100、1111 等编码码距为 2。 任何一位发生变化,如 0000 变成 1000 就从有效编码变成了无效编码,容易检测到这种错误
校验码中增加冗余项的目的就是为了增大码距
码距 ≥ e+1 : 可检测 e 个错误
码距 ≥ 2t+1 : 可纠正 t 个错误
码距 ≥ e+t+1 : 可纠正 t 个错误,同时检测 e 个错误(e ≥ t)