概要:本文将简要介绍两种海明码的检错原理,虽然说是两种,实际上原理上差不多= =。。
且,前两种均只能纠错和检错一个比特。
前置🧀:[偶校验]
海明码的检测基础
利用简单的奇偶校验来确定出错位。即在有效位( D i D_i Di)中加入几个校验位( p j p_j pj)形成海明码( H k H_k Hk)(以下面的图1来举例,海明码是P1 ~ D11),并把海明码的每个二进制位分配到几个奇偶校验组中。当某一位出错之后,就会引起有关的几个校验位的值发生变化,这不但能发现错位,还能指出错位的位置,为自动纠错提供依据。若没有特殊说明,海明码采用偶校验
其一:多异或校验组
校验组的划分
现给出一个 4 ∗ 4 4*4 4∗4的矩阵,白色右下角的为该矩阵格子的以二进制形式表示索引标签,其中基数为10表示的索引标签1到15里面存放着信息,0号闲置。如图1:
[图1]
而在 1~15号下标中,P 为奇偶效验位,D 为有效信息位。不同的P将D划分成了不同的校验组。
而P的二进制索引标签中只有一个位置是为 1 1 1,其余位置均为 0 0 0,这也代表了它起到了标志的作用,这就意味着校验组中的P中为1的位置,所有D的二进制索引标签中也为1.
具体的:
-
P1 其索引标签的二进制表现形式为:
0001
,四个位中只有最右边的第一位是 1 1 1其余均为 0 0 0。因此,P1 就划分所有二进制表示的索引标签中满足: 最 右 边 的 第 一 位 是 1 最右边的第一位是1 最右边的第一位是1的D。
有:D1:
0011
,D2:0101
,D4:0111
,D5:1001
,D7:1011
,D9:1101
,D11:1111
。并成为这些D的偶校验位,即与这些D的异或结果为0,由于偶校验的特性,可得知,P1的值即为这些D的异或结果。P1=D1⊕D2⊕D4⊕D5⊕D7⊕D9⊕D11
由于是偶校验,所以有:P1⊕D1⊕D2⊕D4⊕D5⊕D7⊕D9⊕D11=0
为了表述方便,上式中等式左边的表达式称为P1的校验组
如图2粉色框:
[图2]
-
P2 其索引标签的二进制表现形式为:
0010
,四个位中只有第二位是 1 1 1其余均为 0 0 0。因此,P2 就划分所有二进制表示的索引标签号中满足: 第 二 位 是 1 第二位是1 第二位是1的D。
P2=D1⊕D3⊕D4⊕D6⊕D7⊕D10⊕D11
即:P2⊕D1⊕D3⊕D4⊕D6⊕D7⊕D10⊕D11=0
如图3粉色框:
[图3]
-
P3其索引标签的二进制表现形式为:
0100
,四个位中只有第三位是 1 1 1其余均为 0 0 0。P3=D2⊕D3⊕D4⊕D8⊕D9⊕D10⊕D11
即:P3⊕D2⊕D3⊕D4⊕D8⊕D9⊕D10⊕D11=0
同理可得,如图4粉色框:
[图4]
-
P4其索引标签的二进制表现形式为:
1000
,四个位中只有第四位是 1 1 1其余均为 0 0 0。P4=D5⊕D6⊕D7⊕D8⊕D9⊕D10⊕D11
P4⊕D5⊕D6⊕D7⊕D8⊕D9⊕D10⊕D11=0
同理可得,如图5粉色框:
[图5]
通过上面的异或组合不难看出,每一个校验位都对应着一个校验组,并确保校验组中的异或结果为 0 0 0.
经过某次传输之后,要想检验数据是否出错,可以再对校验组进行一次异或运算,因为在确定校验位P的时候,已经确保了其校验组的异或结果一定为 0 0 0。若传输之后校验组的再次异或之后的结果不为0,则说明该异或组中出现了 奇 数 奇数 奇数个数据位的改变(奇偶效验码的特性)。
原理模拟
假设在某次传输过程中D7发生了数据位的改变(0变1或1变0),且其他信息位均没有发生跳变,则其所在的校验组的异或值都将会变成1(原来为0),此时这些校验组中的公共交集部分即为数据位发生改变的位置。
P1⊕D1⊕D2⊕D4⊕D5⊕D7⊕D9⊕D11 = 1
P2⊕D1⊕D3⊕D4⊕D6⊕D7⊕D10⊕D11 = 1
P3⊕D2⊕D3⊕D4⊕D8⊕D9⊕D10⊕D11=0
P4⊕D5⊕D6⊕D7⊕D8⊕D9⊕D10⊕D11 = 1
以下从图6.1~6.3展示了如何通过利用以上三个校验组表示的范围公共交集确定错误位的方法。
[图6.1]
P1的校验组异或结果为1,说明其范围内发生数据位的改变。
[图6.2]
P2的校验组异或结果为1,说明其范围内发生数据位的改变。
[图6.2]
P4的校验组异或结果为1,说明其范围内发生数据位的改变。
[图6.3]
最终得到的交集即为出现错误的位置,如图6.3所示。
当然,其巧妙之处还不止于此,如果你尝试去异或那四个校验组并将结果按照P1~P4从低位到高位拼接成二进制索引下标:1011
,你就会发现该结果表示的正是出错位D7的二进制序号,如要修正,取反即可。
通过这么多的讲解,大家应该发现了,(假设 X X X X XXXX XXXX为二进制序号下标)
异或P1所在校验组,相当于询问(判断), X X X XXX XXX_ 所有下标序号第一位为1的格子的异或结果是否为0
异或P2所在校验组,相当于询问(判断), X X XX XX_ X X X 所有下标序号第二位为1的格子的异或结果是否为0
异或P3所在校验组,相当于询问(判断), X X X_ X X XX XX 所有下标序号第三位为1的格子的异或结果是否为0
异或P4所在校验组,相当于询问(判断),__ X X X XXX XXX 所有下标序号第四位为1的格子的异或结果是否为0
- 如果为0,说明没有没有发生数据位的改变(或是发生了偶数次)
- 反之,这说明这些数据位中有发生1个数据位(或是奇数次的)改变的
- 每次异或一个校验组,就可以确定一个二进制索引下标的比特位的(出错or正常)信息,异或完所有四个校验组即可确定出错位置(只有发生了一次位跳变的情况才可确定)。
例子
现有有效信息位D11~D1分别为: 11101000100 11101000100 11101000100 如图7所示
[图7]
可得:
P1 = (0011)0⊕(0101)1⊕(0111)0⊕(1001)0⊕(1011)1⊕(1101)1⊕(1111)1=0
P2 = (0011)0⊕(0110)0⊕(0111)0⊕(1010)0⊕(1011)1⊕(1110)1⊕(1111)1=1
P3 = (0101)1⊕(0110)0⊕(0111)0⊕(1100)0⊕(1101)1⊕(1110)1⊕(1111)1=0
P4 = (1OO1)0⊕(1010)0⊕(1011)1⊕(1100)0⊕(1101)1⊕(1110)1⊕(1111)1=0
[图8]
校验
假设我们这次出错的位置与上面模拟的一样是D7,且其他信息位均没有发生跳变。
则整个信息矩阵如下图所示
[图9]
则四个校验组的异或结果为:
(P1)0⊕(0011)0⊕(0101)1⊕(0111)0⊕(1001)0⊕(1011)0⊕(1101)1⊕(1111)1=1
(P2)1⊕(0011)0⊕(0110)0⊕(0111)0⊕(1010)0⊕(1011)0⊕(1110)1⊕(1111)1=1
(P3)0⊕(0101)1⊕(0110)0⊕(0111)0⊕(1100)0⊕(1101)1⊕(1110)1⊕(1111)1=0
(P4)0⊕(1OO1)0⊕(1010)0⊕(1011)0⊕(1100)0⊕(1101)1⊕(1110)1⊕(1111)1=1
(P4)(P3)(P2)(P1)=1011,即为异常位。
其二:整体异或
这校验位计算太麻烦了?
上个例子中,每个校验位都要进行一长串的异或运算,其中还有不少的D是重复计算的,这时人类偷懒的天性就体现出来了。如何能尽可能简便的运算呢?
一方面,我们知道,对几串不同的二进制位进行异或运算是一个有效的计算一组(看成对其的列)单独的奇偶校验的方法(如下图10)。另一方面,校验位的作用是保证其对应的校验组的异或结果为
0
0
0,因此,我们可以将每一个信息位置为一的索引下标的二进制形式当成一个二进制串,然后对这几个二进制串进行异或运算,从上面我们知道,假设索引下标由四位二进制表示,则从低位
1
1
1到高位
4
4
4分别对应P1~P4 ,所以这些对应位的异或结果即为对应P的数值。如图11
[图10 ]
[图11]
再具体的,可以看下面的[图12]
[图12]
注:如果最终的异或结果有多个位为1,其处理过程是重复多次上面的过程。
校验
检验的方法与上面那个方法:将四个校验组的异或结果按低位到高位进行拼接,即可得到出错的位置。类似,我们将所有信息位为 1 1 1的索引下标进行异或,所得结果即为出错的索引下标。
假设发送方的消息矩阵如图12所示,在传输过程中位置0110(6)产生了位跳变: 0 − > 1 0->1 0−>1 ,接收方进行异或过程如图13所示。
[图13]
如果有个位从1跳变成0也是用同样的方法进行校验,这里就不演示了。
原理
-
如果在传输的过程中,有一个比特位从 0 0 0-> 1 1 1,因为只有信息位为 1 1 1的索引下标才进行异或,该位变为 1 1 1之后在校验信息时(异或所有信息位为1的索引标签)将参与异或运算,而传输过来异或结果为 0 0 0的异或串中该位并没有参与异或(因为传输前为0),所以在校验时就相当于多异或了一次该位的下标序列,由于传输的异或结果为0,因此校验的结果为该出错位: 0 ⊕ X = X 0⊕X=X 0⊕X=X
假设共有n位信息位:H1~Hn 假设传输方异或结果:Hi1⊕Hi2⊕..⊕Hin=0 (Hi表示消息位为1的位置,且1<=in<=n) 传输过程中第j位Hj产生跳变:0->1 (j∈[1,n]且∉[i1,in]) 接收方检验:Hi1⊕Hi2⊕..⊕Hin⊕Hj=0⊕Hj=Hj 因此校验之后可得出错位
可参考图13。
-
同理,如果在传输的过程中,有一个比特位从 1 1 1-> 0 0 0,因为只有信息位为 1 1 1的索引下标才进行异或,那么将会在检验信息时从那堆异或的不同位串中消失。那么如何做到将其剔除呢?根据异或的特性: X ⊕ X = 0 X⊕X=0 X⊕X=0,可以得知,要想剔除出错位,再异或一次二进制串即可,同上面:由于传输的异或结果为0,因此校验的结果为该出错位: 0 ⊕ X = X 0⊕X=X 0⊕X=X
假设共有n位信息位:H1~Hn 假设传输方异或结果:Hi1⊕Hi2⊕..⊕Hin=0 (Hi表示消息位为1的位置,且1<=in<=n) 传输过程中第j位Hj产生跳变:1->0 (j∈[i1,in]) 接收方检验:Hi1⊕Hi2⊕..⊕Hin⊕Hj=0⊕Hj=Hj 因此校验之后可得出错位
扩展汉明码
-
上面的两种校验码均只能检验与纠正一比特的错误,当出现多个错误位时,将无法正确定位出错位置,因为海明码本质是利用 ⌈ 二 分 ⌋ \lceil二分\rfloor ⌈二分⌋的思想来查找错误位置的,当出现多个位置的错误时,将失去二分查找中的唯一性这一条件,但是我们的奇偶校验组还是会检测出有错误。且,根据二分查找的特性,在 N N N个信息位中,所需的校验组的数量,即P的个数为 l o g 2 N log_2N log2N个(除去第0位全校验位)。
-
上面的矩阵中,第 0 0 0号格子一直处于闲置状态,我们可以尝试着让其传递一些信息。很容易想到让他充当整个矩阵的校验位,让整个矩阵异或结果为 0 0 0。当且仅当所有检验组的异或结果为 0 0 0与整体的异或结果也为 0 0 0时,就表明所有的信息都没有发生错误;如果整体校验结果为 0 0 0,且有多个校验组出错(即上面1.提到的多个位出错),则说明至少有两个比特位出错;反之,则可以正常的检测出错误的那个位置并修正(取反即可)。
这就是扩展海明码,与上面的两种的区别就在于:
可以检测两位错误(此时不能修正),与修正一位错误(仅当检测到一位错误时)
补全其二中例子的信息位,如图14
[图14]
计算公式
由上面的**[扩展海明码-中的1.]**可知,
对于一般非拓展的 N ( n 位 有 效 信 息 位 + k 位 校 验 位 ) N(n位有效信息位+k位校验位) N(n位有效信息位+k位校验位)位海明码来说所需的校验位数量 k = l o g 2 N k=log_2N k=log2N个,所以有:
2 k = N 2^k=N 2k=N
2 k = n + k 2^k=n+k 2k=n+k
由于上式不一定恒成立,如下面的例题。所以至少要保证,校验位所能表示的状态数要大于所有海明码的位数。
2 k > = n + k 2^k>=n+k 2k>=n+k
又因为,海明码从下标1开始编号,而 2 k 2^k 2k所能表示的范围为 0 0 0~ 2 k − 1 2^k-1 2k−1,所以 k k k位校验位能表示的状态数为 2 k − 1 2^k-1 2k−1个
2 k − 1 > = n + k 2^k-1>=n+k 2k−1>=n+k
2 k > = n + k + 1 2^k>=n+k+1 2k>=n+k+1
对于扩展的海明码而言,需要从原本的 k k k位校验位中抽取一位出来拿来当全校验位(如上面中的 0 0 0号位),此时这个校验位就不能代表一个校验组了,换言之,校验位的有效的表示范围 0 0 0~ 2 k − 1 2^k-1 2k−1 到 0 0 0~ 2 k − 1 − 1 2^{k-1}-1 2k−1−1 了,这里不理解的建议重读其一:多异或校验组部分。此时就有不等式:
2 k − 1 > = n + k + 1 2^{k-1}>=n+k+1 2k−1>=n+k+1
例题
确定 01001110 01001110 01001110的海明码
对于一般非扩展海明码,假设有 k k k位校验位。 n = 8 n=8 n=8位有效信息位。根据上面的公式
2 k > = n + k 2^k>=n+k 2k>=n+k
k = 3 k=3 k=3: 2 3 < 3 + 8 + 1 2^3<3+8+1 23<3+8+1
k = 4 k=4 k=4: 2 4 > 4 + 8 + 1 2^4>4+8+1 24>4+8+1
故 k k k取4,按其一:多异或校验组中的方法填写矩阵。如图15
[图15]
然后按索引下标递增的顺序填写海明码中位串从右往左。即010011111011 这便是非扩展汉明码
对于扩展汉明码,根据公式 2 k − 1 > = n + k + 1 2^{k-1}>=n+k+1 2k−1>=n+k+1
k = 4 k=4 k=4: 2 3 < 4 + 8 + 1 2^3<4+8+1 23<4+8+1
k = 5 k=5 k=5: 2 4 > 5 + 8 + 1 2^4>5+8+1 24>5+8+1
故 k k k取4
填写的上面的那个差不多,只需要使0号位成为整个矩阵的偶校验位即可。但是需要注意,因为海明码的索引编号是从1开始的,为了使原来的校验组正常工作,我们需要将这0号位移到最高为位前面。如图16
图[16]
读取顺序与上面的也一样:即0010011111011 这便是扩展汉明码