做海明码最容易理解的方法就是画一个校验码公式表:
先说下海明码怎么形成,(因为你给的原始数据为8位,加4位冗余,12位我的表格就画不下了,表格对不齐你也不便理解~)
所以下面假设的是接收端收到的、以包含原数据+校验位的数据是01101001,现在对恢复原始数据,剔除校验做解释:
信息数据为01101001,校验码4位
位数 8 7 6 5 4 3 2 1
信息位 / I4 I3 I2 / I1 / /
校验位 r3 / / / r2 / r1 r0
以上即校验公式表,三行八列, “/”的地方为空。
将原始数据填入表中,于是得到:
位数 8 7 6 5 4 3 2 1
信息位 / 1 1 0 / 0 / /
校验位 0 / / / 1 / 0 1
即把原始数据从右到左,对应填入表中。比如原始数据最右边一位是1,就在表的位数行1的非“/”处填1;从右数第二位是0,就在表中位数行2的下面非“/”处填0,第三位是0,在表中行数为3的下面非“/”处填0.....
即表中 I4 I3 I2 I1 就是原始数据,对应01101001的7 6 5 3位,1100
表中r4 r3 r2 r1 就是校验位,对应01101001的8 4 2 1位 0101
回到原问题,对01101001编码,只需扩充表格为12列的就可
信息位行中 2的n次方 处为空,即1 2 4 8 16处为“/”
校验位行中 2的n次方 处为有效位 即1 2 4 8 16处为r4 r3 r2 r1
解释完毕,不知道能不能理解~
呼
正确答案为:0101 1100 1001
海明码详解:
海明码其实也不难,相对于寄偶检验码 它不仅可以检验出错误,还能修正错误!但只能是检验、修正一位错误!说一大堆理论是没什么意思,下面将通过一个例子,尽可能的用最通俗易懂的方式进行讲解!最后大家会发现海明码很神奇!!
假设要传送的数据为:1011 0011
校验流程如下:
一:确定校验位并插入到有效数据位中。
相比奇偶校验只插入一个检验码,海明码需要插入多个检验码,插入的位数与有效数据位数相关,公式如下
公式:2^r-r>k+1,其中r就是要插入检验码的个数,取满足条件的最小整数,k是有效数据位数。因为我们要传送的数据是:1011 0011,显然k=8,推出r=4。也就说我们要将4个校验位插入到有效数据中,怎么插入呢?按照如下规则:
插入位置固定为2^N(N:0,1,2,3,4,5……)处,因为r=4,即只需要取4个有{2^0,2^1,2^2,2^3},对应位置即是1,2,4,8,当然了,如果r=5,那么插入位置为:1,2,4,8,16.同类可以推出其他情况,不再啰嗦。(之所以选择这样的位置插入,是为了有效的分组,保证后面的校验分组能有效的错开,不会互相干扰,这句话不需要理解,到后面就能体会!)
通过分析得到待传送的数据为:xx1x 011x 0011,4位校验位+8为有效数据位。
二、确定校验位的数值。
显然X只能取0,1,下面确定x的值:
由一可知待传送数据为:xx1x 011x 0011。
规则:以X的位置为长度,依次从待传送数据中取X个数,然后跳过X个数,再取X个数,直到待传送数据串尾,得到一个子串,然后统计子串中1的个数,如果为奇数,则x=0,为偶数,x=1(当然,反过来也行,其实这就是奇偶校验的规则,想了解奇偶校验可以参见我以前的回答的,这里不了解也行)
第1个X:位置为1,从第1个位置开始依次取1个数据,并跳过1个数据再取,直到串尾得到一个子串:
{x 1 0 1 0 1},这个串可记为第1个校验组, 因为1的个数是3个为奇数,故x=0.
第2个X:位置为2,故从第2个位置开始依次取2个数据,并跳过2个数据再取,直到串尾得到一个子串:
{x1 11 01} ,记为第2个校验组,因为1的个数为4是偶数,故x=1.
第3个X:位置是4,故从第4个位置开始依次取4个数据,并跳过4个数据再取,直到串尾得到一个子串:
{x011 1},记为第3个校验组,因为1的个数为3是奇数,故x=0.
第4个X:位置是8,故从第8个位置开始依次取8个数据,并跳过8个数据再取,直到串尾得到一个子串:
{x0011 },记为第4个校验组,……,X=1。
故得到最终的待传送的数据串为:0110 0111 0011。
这里其实就可以看到了,为什么X的位置要取2^N,这样才能保证各个校验位不会相互干扰。
经过以上一、二步骤就完整了海明码的构造过程,下面讲解校验过程:
三、根据步骤二中的构造规则,取出各校验组
发送的数据串为:0110 0111 0011。
假设接受到的数据串为:0110 0111 1011(注意和传送数据串相比,第9为出现了错误!)
规则:以X的位置为长度,依次从待传送数据中取X个数,然后跳过X个数,再取X个数,直到待传送数据串尾,得到一个子串,然后统计子串中1的个数,如果为奇数,则x=0,为偶数,x=1(规则必须和步骤二中一样)
根据二中制定的规则再次取出各个校验组。
第1个校验组:从第1个位置开始依次取1个数据,并跳过1个数据再取,直到串尾得到一个子串:{0 1 0 1 1 1}。
第2个校验组:从第2个位置开始依次取2个数据,并跳过2个数据再取,直到串尾得到一个子串:{11 11 01}
第3个校验组:从第4个位置开始依次取4个数据,并跳过4个数据再取,直到串尾得到一个子串:{0011 1}
第4个校验组:从第8个位置开始依次取8个数据,并跳过8个数据再取,直到串尾得到一个子串:{11011}.
四、根据步骤二的构造规则,确定存在错误的校验组,并通过错误校验组的交集,最终确定出错的位置。
由步骤三得到4个校验组:
1:{0 1 0 1 1 1}。 对应位置为{1 3 5 7 9 11}
2:{11 11 01}。 对应位置为{2 3 6 7 10 11}
3:{0011 1} 。对应位置为{4567 12}
4:{11011}。 对应位置为{8 9 10 11 12}
因为我们的构造规则是:统计子串中1的个数,如果为奇数,则x=0,为偶数,x=1。
所以正确的校验组中1的个数绝对是奇数!(好好琢磨,很容易就想通了,如果我们的规则是为奇数,则x=1,为偶数,x=0。那么正确的校验组中1的个数绝对是偶数),所以如果校验组1的个数不是奇数,那么这个校验组就存在问题。因而可以判断第1个和第4个校验组出现问题了。
确定了第1个和第4个校验组出现问题后,找到这两个校验组的交集即第9个位置和第11个位置是它们交集,即共同校验的位置。于是判断出现问题的位置要么就是第9个位置,要么就是第11个位置!因为在第2个校验组中有第11个位置,故第11个位置绝对没有出错,因为就可以判断是第9个位置出现错误!
到这里,应该懂了吧?但是不是觉得找出错位置有点麻烦啊?下面就给出一个具体的实现方法,理解了上面的描述,再了解下面实现的方法,立马就能确定出错误的位置:
首先:我们对各个校验组求异或。
第一个校验组:{0 1 0 1 1 1} 异或的结果为:0
第二个校验组:{11 11 01}异或的结果为:1
第三个校验组:{0011 1} 异或的结果为:1
第四个校验组:{11011}异或的结果为:0
接着:倒置拼接异或结果,得到:0110,
最后:按位取反的到:1001,。
大家有没有惊奇的发现1001的十进制数就是9,这不就是出错的位置吗?这是巧合吗?
不急再看一个例子:
传送的数据串为: 0110 0111 0011(还是我们开始的那个串)
接受到的数据串为:0110 1111 0011(和正确数据串相比,第5个位置出错了)
第一个校验组:{0 1 1 1 0 1} 异或的结果为:0
第二个校验组:{11 11 01}异或的结果为:1
第三个校验组:{0111 1} 异或的结果为:0
第四个校验组:{10011}异或的结果为:1
倒置拼接:1010 反转为:0101 对应十进制数为5!
也就是说方法是真确的!!不用怀疑!!这也就是海明码的奇妙之处!
再来看看一个例子:
传送的数据串为: 0110 0111 0011(还是我们开始的那个串)
接受到的数据串为:0110 0110 0011(和正确数据串相比,第8个位置校验位出错了)
显然这是校验位出错了,那么能不能校验出来呢?
第一个校验组:{0 1 0 1 0 1} 异或的结果为:1
第二个校验组:{11 11 01}异或的结果为:1
第三个校验组:{0011 1} 异或的结果为:1
第四个校验组:{00011}异或的结果为:0
倒置反转结果为1000 正好是8,所以也没问题。
下面我们来说下规则:(其实就是说异或与奇偶的关系,想拓展的就可以看看)
上面的例子中,我们规定: 统计子串中1的个数,如果为奇数,则x=0,为偶数,x=1。如果是按这样的规定,那么校验组中1的个数必定是奇数,正是因为如此,所以校验组中如果1的个数不是奇数那么肯定出现了错误!而如果一个串中1的个数是奇数,那么串异或的结果一定为1,其实这个规则对应的就是奇校验!反之,如果为奇数,则x=1,为偶数,x=0,那么对应的就是偶校验!
故得到以下结论:
如果采用奇检验构造海明码,那么出错校验组中的1的个数必为偶数,即异或的结果必定为0!
如果采用奇检验构造海明码,那么出错的位置是校验组异或结果倒置拼接并反转的十进制数
如果采用偶检验构造海明码,那么出错校验组中的1的个数必为奇数,即异或的结果必定为1!
如果采用偶检验构造海明码,那么出错位置是校验组异或结果直接倒置拼接的十进制数!
关于偶检验构造海明码这里就不再详细展开,如果你能用偶检验的方法在把上面的例子都做一遍,那么海明码你就已经完全弄懂了!试试吧!
关于奇偶检验码 建议还是看看,因为海明码是基于奇偶校验的改进!而且奇偶校验更简单!