海明码(汉明码)原理简易理解
一、序言
- 老鼠试毒:
- 最近碰到了一个简单的计算题,问题大概是现在Doctor有n瓶药水,其中只有一瓶有毒,Doctor现在想用老鼠试毒来测试出其中的毒药水,如果要求第一天m只老鼠喝下药水,每只老鼠可以喝不止一瓶药水,第二天喝到毒药水的老鼠都会死去,以此来判断哪一瓶药水有毒,于是求对于n瓶药水至少需要多少只老鼠来试毒。
- 这个问题答案很简单,就是 m = l o g 2 n m=log_{2}n m=log2n 当然结果得向上取整。举个例子,如果有8瓶药水,那么至少需要3只老鼠,可以这么来理解:一只老鼠再喝完毒药后会有两种情况——dead or live,那么三只老鼠的生死组合起来就有 2 3 2^3 23种情况,说白了他们可以表示8种信息,对应的也就是8瓶药水的带毒情况,至于怎么实现试毒的,我们结合后面的海明码来加以解释。
本文作者还在上大一,故不会用很专业的术语来对海明码进行解释,主要力求便于理解
二、海明码
- 汉明码(Hamming Code),是在电信领域的一种线性调试码,以发明者理查德·卫斯里·汉明的名字命名。汉明码在传输的消息流中插入验证码,当计算机存储或移动数据时,可能会产生数据位错误,以侦测并更正单一比特错误。
- 上文为海明码在百度上的解释,最重要的莫过于颜色加深的部分,它主要用于一位纠错。
三、偶校验
- 偶校验使用异或运算来检验错误,例如
0101 0110
这一比特串,按位异或后应为0,那么我们用0
作为校验码,传输数据中如果出现1比特错误,那么比特串异或结果为1
,显然与校验码不符合,检测出了错误,但无法确定具体位置,所以想要找到出错位置,就应该多找几只老鼠(校验码)来试毒。
四、海明码一位纠错的实现
- 结合序言的思想,我们将k个校验码对应老鼠,n个数据码对应药水,那么应该满足
2
k
>
=
n
2^k>=n
2k>=n不过显然不是这样的:
公式应该为: 2 k > = n + k + 1 2^k>=n+k+1 2k>=n+k+1
这是因为数据码会和校验码一起传输,所以校验码也可能出错,此外还有1种没有出错的可能,所以右侧应该为n+k+1。 - 有了k个校验码之后就很简单了,也就是现在有n+k个数据,我们可以将他们的位置用二进制来表示,例如第5个数据位置可以用
0000 0101
来表示,然后我们把校验码放在 2 k 2^k 2k次幂位置上,也就是0000 0001,0000 0010,0000 0100,0000 1000......
等位置上,然后数据码填充剩余的位置。 - 接下来要做的事情就是偶校验,比如第三个校验码的位置为
0000 0100
,它的第三位位置为1,那么我们就将同样第三位为1的数据码拿出来与这一校验码进行偶校验,根据上述第三点偶校验的知识,我们可以判断校验的这些数据码是否有错误。当然,在对每一个校验码都进行偶校验之后,我们就能得出哪些校验码出问题了,如果是校验码1和校验码3出问题了,说明错误的比特位置第1位和第3位为1,也就是0000 0101
,所以实际上我们只需要将出错的校验码位置相加所得的数据码取反,就能实现纠错。