海明码(汉明码)
海明码具有一位纠错能力。
校验码位数
假设数据有m位,校验码有p位,则校验码一共有 2 p 2^p 2p种取值。加上校验码之后一共有 m + p m+p m+p位,每一位都有可能出现错误,或者没有错误,所以有 m + p + 1 m+p+1 m+p+1种可能。
因此若想通过校验码指出任一位上发生的错误必须满足:
2
p
≥
m
+
p
+
1
2^p \geq m+p+1
2p≥m+p+1
例如:数据1010的校验码 p p p满足 2 p ≥ 4 + p + 1 2^p \geq 4+p+1 2p≥4+p+1,最终的到校验码 p ≥ 3 p \geq 3 p≥3。
校验码位置
校验码放在 2 n ( n = 0 , 1 , 2... ) 2^n(n=0,1,2...) 2n(n=0,1,2...)位置上。
例如1010, m = 4 , p = 3 m=4,p=3 m=4,p=3,对应的海明码如下:
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
p 1 p_1 p1 | p 2 p_2 p2 | 1 | p 3 p_3 p3 | 0 | 1 | 0 |
校验位计算
第一个校验位
p
1
p_1
p1是位于1的位置,它检验的位置是1,3,5,7,也就是读一位,隔一位,但1是属于校验位可除外,所以校验的是3,5,7(下同)
第二个校验位
p
2
p_2
p2是位于2的位置,它检验的位置是3,6,7,也就是读两位,隔两位
第三个校验位
p
3
p_3
p3是位于4的位置,它检验的位置是5,6,7,也就是读四位,隔四位
以此类推,可得知,第
n
+
1
n+1
n+1位校验位校验的海明位是,从自身开始,读
2
n
2^n
2n位,隔
2
n
2^n
2n位。
知道校验位后 ,对校验位对应的数据进行异或运算(默认是偶校验),即
p
1
=
1
⊕
0
⊕
0
p
2
=
1
⊕
1
⊕
0
p
3
=
0
⊕
1
⊕
0
p_1=1⊕0⊕0 \\ p_2=1⊕1⊕0 \\ p_3=0⊕1⊕0
p1=1⊕0⊕0p2=1⊕1⊕0p3=0⊕1⊕0
若采用奇校验,则将各校验位的偶校验值取反即可。即
偶
校
验
p
1
=
1
,
p
2
=
0
,
p
3
=
1
奇
校
验
p
1
=
0
,
p
2
=
1
,
p
3
=
0
偶校验p_1=1,p_2=0,p_3=1 \\ 奇校验p_1=0,p_2=1,p_3=0
偶校验p1=1,p2=0,p3=1奇校验p1=0,p2=1,p3=0
由此得到偶校验下的海明码和奇校验下的海明码如下:
位 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
偶 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
奇 | 0 | 1 | 1 | 0 | 0 | 1 | 0 |
检验错误
根据上面的方法,可以得知每个校验位负责检测的海明位,将校验位与其所负责检测的海明位进行异或运算即可。
注意这里的位3,位5,位6,位7是接受方接收到的对应的值
e
1
=
p
1
⊕
位
3
⊕
位
5
⊕
位
7
e
2
=
p
2
⊕
位
3
⊕
位
6
⊕
位
7
e
3
=
p
3
⊕
位
5
⊕
位
6
⊕
位
7
e_1=p_1⊕位3⊕位5⊕位7 \\ e_2=p_2⊕位3⊕位6⊕位7 \\ e_3=p_3⊕位5⊕位6⊕位7
e1=p1⊕位3⊕位5⊕位7e2=p2⊕位3⊕位6⊕位7e3=p3⊕位5⊕位6⊕位7
若采用偶校验,则
e
3
e
2
e
1
e_3e_2e_1
e3e2e1全为0表示数据没有错误;
若采用奇校验,则 e 3 e 2 e 1 e_3e_2e_1 e3e2e1全为1表示数据没有错误。
当发生错误时,将 e 3 e 2 e 1 e_3e_2e_1 e3e2e1的值转化为十进制即可知道发生错误的位置,如 e 3 e 2 e 1 e_3e_2e_1 e3e2e1=101,即表示位5这个位置的数据发生了错误,只要将其取反即可纠正。