算法(二)|深入浅出的讲解海明码的原理

目录

0.前言

1. 海明码的使用

2.理解海明码需要明白的知识

a.奇偶校检法

b.异或运算

3.海明码的原理

a.海明码原理的概述

b.多个校检位的设计

c.校检位个数的计算

d.海明码的总结

扫描二维码关注公众号,回复: 14799052 查看本文章

4.举例

a. 计算校检码的个数

b. 计算每一位校检码并且与数据码组合

c. 数据传出,检错验错


0.前言

最近在学计组,碰到了海明码,但是书上数学语言有点晦涩难懂,而且并没有给出一部分细节的说明(比如为什么2^k -1 >= n+k),去网上搜索发现,好像网上都没有去做海明码的原理的详细讲解,大多教给你怎么用(那小萌新我来填补一下遗憾吧)。这一篇博客目的是以浅显能懂的语言,告诉你海明码检验和纠错的基本原理,来揭开海明码神奇的面纱吧!

1. 海明码的使用

首先,我们来看海明码的使用案例,网上有很多佬已经做了很多特别详细的讲解,这里我抽一篇,看完这个,相信你对海明码有了初步认识,会怎么用了。

  (147条消息) 《汉明码(海明码)》通俗易懂_苏某的橡皮擦的博客-CSDN博客

2.理解海明码需要明白的知识

a.奇偶校检法

奇偶校检法主要用于检验传出的数据是否发生错误,它能检验出1位(出现了奇数次错误,理论都应该检测的出来)错误,不能改正错误的校检方法。它的核心原理是,规定传出的二进制串,1出现的次数应该是奇数或者偶数,根据校检位来检测错误。

例如,若用奇数校检法,规定1出现的个数为奇数,如果数据为 0001,则检验没有错误,加入校检位0,则是0 0001。如果接受的数据为 0011,则应该加入校检位1(为了使1出现的次数为奇数),则是1 0011,因为校检位为1,说明数据发生了错误,需要重传。偶数校检法同理,对校检位的检测,如果是1,则说明数据发生错误,如果是0,则说明没有错误。这就是奇偶校检法。

b.异或运算

异或运算是二进制运算,异或运算是比较二进制,如果相异,则取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出现的次数的奇偶性,我们可以对数据进行异或操作。

3.海明码的原理

a.海明码原理的概述

海明码的原理是 多组奇偶校检+哈希表查找 的原理,在检验数据有没有出错是用的多组奇偶校检,而在查找是哪个数据出错,则用了哈希表的原理。海明码用于1位检错和1位纠错,但若再引入一个全局校检码,则可用于2位检错。

b.多个校检位的设计

对数据的检错,其实只需要一个校检位就可以检查出错误,但是海明码用了多个校检位,校检位与数据位结合后,将校检位放到了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。

c.校检位个数的计算

检验的范围应该是检验位的二进制组合能够表示的范围,假设有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位海明码。

d.海明码的总结

海明码多个检验码的引入,不是为了检验错误(检验错误只需要1个检验码即可),而是为了查找到错误的位置。通过对检验位二进制的组合,即可得到错误的位置,这便是海明码的神秘面纱,海明码的巧妙之处,这就是为什么说海明码的查错原理类似哈希表的查找原理,根据值来确定索引。 另外,海明码用于1位检错和1位纠错,如果错误的位数超过2,如果引入1个全局校检码,则可以检错,但不能纠正,只能重新传入数据。

4.举例

我们要传入4位数据1010,我们按照偶数校检的方式(最好是偶数检错,这样更容易理解),1出现的个数只能为偶数次,下面是海明码的过程。

a. 计算校检码的个数

根据公式2^k-1 >= n+k,则我们可以计算得到4位数据码应该需要3位校检码。

b. 计算每一位校检码并且与数据码组合

假设数据是按照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

c. 数据传出,检错验错

数据传出后,我们还需要校检一次(新校检码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,则说明第一位出现了错误。

猜你喜欢

转载自blog.csdn.net/DADONGOOO/article/details/129578477