• 关于Hamming校验纠错算法的证明


    首先说Hamming算法是什么。

    没有查过原始的文献,所以没见过它原始的定义和证明。依照现在手头上的<<Structure Computer Organization>>一书上的说明。

    Hamming算法可以对任意字长的内存建立起纠正码(注意,是不止可以检验出错误,还可以纠错)。原理如下:

            

             假设原始的数据有m位,向这m位数据里加入r位检验位,就得到m+r位的字长。在这m+r位里,所有2的整数幂的位是检验位,其他的是数据位(注意这里的位都是从1开始计数的,而不是从0开始)。

    每一个校验位可以检验特定的位。

             例如,一个16位的字就需要加入5位的校验位,即第1、2、4、8、16位为校验位。此时的实际字长达到21位。第一个校验位负责检验第1、3、5、7、9、11、13、15、17、19、21位,第二个校验位负责检验第2、3、6、7、10、11、14、15、18、19  ……..

             具体如下:

             第1位负责检验:1、3、5、7、9、11、13、15、17、19、21

             第2位负责检验:2、3、6、7、10、11、14、15、18、19

             第4位负责检验:4、5、6、7、12、13、14、15、20、21

             第8位负责检验:8、9、10、11、12、13、14、15、

             第16位负责检验:16、17、18、19、20、21

    那么,怎么知道一个检验位都负责检验哪些位呢?

    Hamming校验码的设置原则是:第B位通常由第b1,b2,b3,…,bj位来检验,其中B=b1+b2+b3+…+bj.

    比如,第5位由第1位和第4位一起校验(5=1+4),第6位由第2位和第4位一起校验(6=2+4)。

    为了说明纠错过程,下面假设有一个这样的16位字:

                  1 1 1 1 0 0 0 0 1 0 1 0 1 1 1 0

    假设使用偶检验,则加入第1、2、4、8、16位校验码后得到的21位字就如下所示:

    (偶检验就是,根据数据位1的个数调整检验位,使得总共1的位数为偶数个)

                                  0 0 1 0 1 1 1 0 0 0 0 0 1 0 1 1 0 1 1 1 0

    假设第五位出错了,变成:

                                  0 0 1 0 0 1 1 0 0 0 0 0 1 0 1 1 0 1 1 1 0

    那么,检验位1和检验位4所在的那个检验列的1的个数都不是偶数个了,所以就知道出错了。

    这时,只要知道哪一位出错了就可以将它纠正回来。

    想要知道哪一位出错,有两种方法:

    第一个是对比分析。比如,上面的例子中,由于第1个检验位和第四个验位所检验的队列都出错了,那么,出错位肯定是他们所共有,而其他队列所没有的。对比一下就知道那就是第5位了。

    第二种方法就是,将出错队列的检验位相加,就得到出错位。上面例子中,1+4=5.

    需要说明的是,这种算法纠错的前提是,它假设出错的位数为1位。也就是说,如果错了3位,这个算法也会以为它只有一位出错(错了2位就检验不出来了,因为奇偶检验的Hamming码距是2)

    我们已经知道这样子可以检错并纠错,但是为什么呢?  如何保证这种算法的正确性?

            如果想做证明,首先很自然的一个疑问是:根据Hamming算法设置校验码的原则(即第B位通常由第b1,b2,b3,…,bj位来检验,其中B=b1+b2+b3+…+bj.),如何保证对于码字中的每一位,都存在一些校验位,这些校验位相加得到这个位?比如,用上面的例子,第17位应该由哪些位检验?由于17比较小,我们很容易知道 17=1+16,从而知道应该是由第1和第16位检验。但是Hamming算法是可以检验任意的位数的,如果那个位很大怎么办? 1000?1000000? 1000292? 显然无法全部枚举。

             再者,怎么知道根据Hamming算法设置校验位的原则所得到的校验位是唯一的?也就是说,对于上面的17,我们已经知道17=1+16,但是怎么知道不会有其他的17 = m + n ?当然,由于17很小,我们可以枚举完,知道不会有其他可能了,但是如果那个位很大呢?1000?10000000? 1232312312?显然也无法枚举完,必须通过严格的数学证明。

             我们首先来证明这两个个问题。证明完了这两个问题,整个证明也就差不多完成了。

             证明如下:

             首先,Hamming算法设置校验位的原则是:所有的2的整数幂的位都是校验位(也就是第1、2、4、8、16、32….位)。

            

       很明显的一点是,每一个位数都不会大于那些存在的校验位相加的最大值,比如说,对于上面的例子的21位,即使是最大的21,也不会比1+2+4+8+16大。因为,给定一个数n, 如果 2^r < n < 2^(r+1) (  在这里 16 < 21 <32 ),那么n必然小于2^0 + 2^1 + 2^2 + … + 2^r, 因为这个等比数列之和等于2^(r+1) 减1.而 n < 2^(r+1), 也就是 n <= 2^r-1.

            

    好,在 2^r < n < 2^(r+1) 的假设下 ,再证明一点,即,如果要有一个和式,2^i + 2^j  + …. + 2^k = n, 那么,里面肯定会有2^r,因为,如果没有2^r的话,即使是2^0 , 2^1 , 2^2……2^(r-1) 全加起来也只有2^r – 1 而已(等比数列求和),更不用说n了,因为2^r < n < 2^(r+1). 所以如果要有一个这样的2的整数次幂的和式,它的和为n的话,里面必须要有一个2^r

    在上面,我们假设有这样一条式子:

                  2^i + 2^j + … + 2^r= n

    即一些2的整数次幂加起来等于n。也说明了其中一个必须是2^r. 其中2^r < n <2^(r+1)

    现在把式子做一下变换,得:

    2^i + …+ 2^j = n – 2^r

    (形式上来说就是将n换成了 n – 2^r )

    现在,令m=n – 2^r

    现在我们就变成了证明存在一个2的整数次幂的和式,其和等于m了:

    2^i + …+ 2^j = m

    由于m=n – 2^r, 而 2^r < n <2^(r+1), 那么可以知道 0 < m < 2^r

    而式子左边的 2^i 和 2^j 的范围是 0 ~ 2^(r-1). 所以所以变换之后又回到之前n的情况。所不同的是,n的范围是 2^r < n < 2^(r+1),  而 m的范围是0 < m < 2^r.

    但是其实本质没有变。我们依然可以找到一个q, 使得2^q < m < 2^(q+1). 而且这个m依然在那些剩下的2^i….. 2^j 之和的表示范围内,这就回到了和之前的n一模一样的情况了。

    所以可以看到,按照这种方式,从n里面不断地减去一个2的次幂,就可以得到一个并且唯一一个和式,使得其和为n

    也就是  2^i + 2^j + … + 2^r= n

    数学上,这叫数学归纳法 :)

    上面我们证明了对于任意一个位 n ,都有且仅有一个和式使得 2^i + 2^j + … + 2^r= n

    也就是说,那个位 n 有唯一的检验位 i 和 j 和 … 和 r

    那么,当我们发现出错的时候,我们就知道出错的那些队列的检验位 i 和 j 和 … 和 r 相加就得到出错位的位置了(也就是n了)。这也就是Hamming校验算法的纠错方式了

    严格的证明就不写了。很难解决文本的格式问题,好难写。

  • 相关阅读:
    如何使用设计模式系列
    网站性能越来越差怎么办
    ASP.NET特殊字符串替换函数
    SQL Server多事务并发问题
    弹出隐藏子菜单
    过滤sql匹配符号 防止sql注入
    统一建模语言UML轻松入门系列
    sql 字符处理函数大全
    并发控制
    类与类之间的关系图
  • 原文地址:https://www.cnblogs.com/walkerlala/p/4950668.html
Copyright © 2020-2023  润新知