目录
0.前言
1. 海明码的使用
2.理解海明码需要明白的知识
a.奇偶校检法
b.异或运算
3.海明码的原理
a.海明码原理的概述
b.多个校检位的设计
c.校检位个数的计算
d.海明码的总结
4.举例
a. 计算校检码的个数
b. 计算每一位校检码并且与数据码组合
c. 数据传出,检错验错
最近在学计组,碰到了海明码,但是书上数学语言有点晦涩难懂,而且并没有给出一部分细节的说明(比如为什么2^k -1 >= n+k),去网上搜索发现,好像网上都没有去做海明码的原理的详细讲解,大多教给你怎么用(那小萌新我来填补一下遗憾吧)。这一篇博客目的是以浅显能懂的语言,告诉你海明码检验和纠错的基本原理,来揭开海明码神奇的面纱吧!
首先,我们来看海明码的使用案例,网上有很多佬已经做了很多特别详细的讲解,这里我抽一篇,看完这个,相信你对海明码有了初步认识,会怎么用了。
(147条消息) 《汉明码(海明码)》通俗易懂_苏某的橡皮擦的博客-CSDN博客
奇偶校检法主要用于检验传出的数据是否发生错误,它能检验出1位(出现了奇数次错误,理论都应该检测的出来)错误,不能改正错误的校检方法。它的核心原理是,规定传出的二进制串,1出现的次数应该是奇数或者偶数,根据校检位来检测错误。
例如,若用奇数校检法,规定1出现的个数为奇数,如果数据为 0001,则检验没有错误,加入校检位0,则是0 0001。如果接受的数据为 0011,则应该加入校检位1(为了使1出现的次数为奇数),则是1 0011,因为校检位为1,说明数据发生了错误,需要重传。偶数校检法同理,对校检位的检测,如果是1,则说明数据发生错误,如果是0,则说明没有错误。这就是奇偶校检法。
异或运算是二进制运算,异或运算是比较二进制,如果相异,则取1,相同则取0,例如1^0 = 1,0^0 = 0等。异或运算的结果可以让我们知道数据中1的个数为奇数还是偶数,若为奇数,则结果是1,若是偶数,则结果是0。异或操作的运算符取^。
例如
1^0 = 1 0^0 = 0 1^1 = 0
1^1^1^0 = 1 0^1^1 = 0 1^0^1^0^1^1 = 0
由此我们可以知道,异或运算的结果可以让我们知道数据中,1出现的次数为奇数还是偶数。因此检验1出现的次数的奇偶性,我们可以对数据进行异或操作。
海明码的原理是 多组奇偶校检+哈希表查找 的原理,在检验数据有没有出错是用的多组奇偶校检,而在查找是哪个数据出错,则用了哈希表的原理。海明码用于1位检错和1位纠错,但若再引入一个全局校检码,则可用于2位检错。
对数据的检错,其实只需要一个校检位就可以检查出错误,但是海明码用了多个校检位,校检位与数据位结合后,将校检位放到了1,2,4,8...的位上。这样做不仅是为了检查错误,更是为了能计算出错的位置,这就是海明码设计的巧妙之处。下面我们进行剖析。
为什么校检位要放到1,2,4,8...的位上呢?首先我们来看一个表
图中的深色是校检码的序号位置,而浅色是数据的序号位置。1,2,4刚好是2^1,2^2,2^3,并且在二进制中,只有1位是1,其他位都是0。
我们按照二进制进行分组,将1,3,5,7分成一组,2,3,6,7分成一组,4,5,6,7分成一组。
我们观察可以发现,这个分组规则就是根据二进制的位数来分,二进制的第一位为1的一组,第二位为1的一组,第三位为1的一组,则可以有下图
如果一个数据不仅处在分组一,也处在分组二,但不处在分组3。说明这个数据二进制的第一位(从右往左)为1,第二位为1,第三位为0,因此是011。如果只处在分组一,说明这个数据的二进制的第一位(从右往左)为1,其他位均为0,则是001。因此我们可以通过数据在哪些分组的情况,从而确认这个数据应该是多少,这就是海明码的查错的核心原理。
因此将检验位设置为1,2,4,8...原因是,我们可以通过检验位二进制的组合可以得到出错的位置。例如,对于检验位p,1表示该组出错,0表示没有出错,若p1 = 0,p2 = 1,p4 = 1,则说明该出错的数据在第二组和第三组,则二进制组合数应该为110,则出错的位置是6。
检验的范围应该是检验位的二进制组合能够表示的范围,假设有2位检验码,则能检验 01 ~ 11的序号位置(不考虑序号0,序号0无法表示),3位检验码,则能检验的范围是3位二进制数的范围,001 ~ 111。因此数据位和检验码的组合数据的任一序号不应该超出这个范围。
k位二进制数能够表示数的个数是 2^k个,但是其中包含了0,因为序号中没有0,所以要减掉1,这就是该公式的推导。
对于n位数据来说,需要校检码的个数要满足上面公式,且k要最小。例如,有4位数据需要传输,假设加入k位检验位,则加入后的总位数应该为k+4,2^k-1 >= k+4且k为整数,所以k>=3,因此需要3位海明码。
海明码多个检验码的引入,不是为了检验错误(检验错误只需要1个检验码即可),而是为了查找到错误的位置。通过对检验位二进制的组合,即可得到错误的位置,这便是海明码的神秘面纱,海明码的巧妙之处,这就是为什么说海明码的查错原理类似哈希表的查找原理,根据值来确定索引。 另外,海明码用于1位检错和1位纠错,如果错误的位数超过2,如果引入1个全局校检码,则可以检错,但不能纠正,只能重新传入数据。
我们要传入4位数据1010,我们按照偶数校检的方式(最好是偶数检错,这样更容易理解),1出现的个数只能为偶数次,下面是海明码的过程。
根据公式2^k-1 >= n+k,则我们可以计算得到4位数据码应该需要3位校检码。
假设数据是按照D1D2D3D4排列
D1 | D2 | D3 | D4 |
1 | 0 | 1 | 0 |
则校检码(以字母p表示)组合后应该为
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
字母 | p1 | p2 | D1 | p4 | D2 | D3 | D4 |
值 | X | X | 1 | X | 0 | 1 | 0 |
p1 = 1 ^ 0 ^ 0 = 1
p2 = 1 ^ 1 ^ 0 = 0
p4 = 0 ^ 1 ^ 0 = 1
则组合后的数据应该为 1011010
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
字母 | p1 | p2 | D1 | p4 | D2 | D3 | D4 |
值 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
数据传出后,我们还需要校检一次(新校检码P),来检查传出的数据有无发生错误
1) 如果传输过程中,数据没有发生错误
P1 = 1(p1) ^ 1^ 0 ^ 0 = 0
P2 = 0(p2) ^ 1 ^ 1 ^ 0 = 0
P4 = 1(p4) ^ 0 ^ 1 ^ 0 = 0
将校检码进行组合后,应该为 P4P2P1,000,说明数据并没有发生错误
2)如果传输过程中,数据第六位发生了错误
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
原来值 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
出错后的值 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
P1 = 1(p1) ^ 1^ 0 ^ 0 = 0
P2 = 0(p2) ^ 1 ^ 0 ^ 0 = 1
P4 = 1(p4) ^ 0 ^ 0 ^ 0 = 1
将校检码进行二进制组合,得到 110 ,转换为十进制为6,则说明第六位出现了错误
3)如果传输过程中,数据第一位发生了错误(校检码出错)
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
原来值 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
出错后的值 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |
P1 = 0(p1) ^ 1^ 0 ^ 0 = 1
P2 = 0(p2) ^ 1 ^ 1 ^ 0 = 0
P4 = 1(p4) ^ 0 ^ 1 ^ 0 = 0
将校检码进行二进制组合,得到 001 ,转换为十进制为1,则说明第一位出现了错误。