计算机在运行程序过程中,存储器、CPU、I/O设备不断进行信息交换。由于结构、工艺、元器件等种种原因有时会使信息出错。
具有指出错误、改正错误能力的编码称为纠错码,又称校验码(Check Code)。
常用的校验码技术有:奇偶校验码,海明码,循环冗余校验码,格雷码等。
这里详细介绍一下前三个
一、奇偶校验码:
1、解决的问题:奇偶校验常用于内存储器的校验,例如IBM PC机内存。它能发现信息在写入、传送、读出时的错误,但不能纠正错误。
2、原理:通过增加一位校验位使得数据中所有位(包括校验位)的1的个数保证为奇数(或偶数)这样在收到数据的时候检测(将所有的位异或起来)数据中1的个数是否仍然是奇数(或偶数)即可知道这个数据是否出错
n位数据代码的最低位后面加上一位校验码,组成了n+1位编码。如果n+1位编码的“1”的个数是奇数,则称为奇校验(Odd Parity);若是偶数,则称为偶校验(Even Parity)。统计“1”的个数常常用异或门电路来实现,
——偶校验
——奇校验
3、缺点:
这种方法只能发现奇数个代码位出错。因为偶数个出错,校验码的奇偶性不发生变化。
这种方法也不能指出出错代码的位置。
奇偶校验之所以被认为可靠,之所以大
量应用是基于数据代码2位同时出错的概率远远小于1位出错的概率的缘故。
4、扩展:
交叉校验:交叉校验是二维奇偶校验。当一次传送一个具有n个字节的数据块时,在每个字节设有一个水平奇偶校验位,或称行校验位;在n个字节的同一位设有一个垂直校验位,又称列校验位。当n=4时,如下所示
字节 |
数 据 位 |
奇校验位(行) |
|||||||
D0 |
D1 |
D2 |
D3 |
D4 |
D5 |
D6 |
D7 |
||
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
2 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
3 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
4 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
奇校验位(列) |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
这样就可以通过两个坐标找到并纠正一位错了,但是仍然不能识别两位错。
二、海明码
1、解决的问题:这是一种基于奇偶校验的校验方法,这样可以防止校验位在传输中出错的问题
海明校验码是一种纠错码。这是由美国计算机科学家R.W.Hamming(海明)发明。海明由此获得了1968年的图灵奖。
2、原理:海明码也是以奇偶校验为基础的,只是校验位有多位。假设要传送的数据信息是1位,用D表示。采用2个校验位X1和X2,因而能表示4种情况,可以用其中一种表 示 无错,其他三种表示出错可能在D、X1和X2。方法是将D 和X1编成C1校验组,D和X2编在C2校验组。每一组形成一个奇偶校验。
D |
X1 |
X2 |
|
C1 |
√ |
√ |
|
C2 |
√ |
√ |
如上表:假设数据位只有1位的时候添加两位校验位,
C2C1=0 0,可确定是D出错。只要将D反相即可纠错。
C2C1=0 1,X2出错,无需纠正。
C2C1=1 0,X1出错,无需纠正。
C2C1=1 1,没有错误
海明码实现:(这里只考虑1位错)
a>要根据数据位的位数来确定使用几位验证位。假设有k个数据位,要加r个校验位,那么要想验证位的所有0/1组合可以表示所有的错误情况和一种全对情况,即满足
k+r+1<=2^r
通过上式可以算出要加的验证位个数,例如当数据是4位的时候要加3位验证位(k==4,r==3)
b>设计验证组:
I. 设计校验码放置的位置,第i个校验码放在第2^(i-1)位置上,以4位数据为例,那么3个验证码分别放在第1、2、4位的位置
II.设计校验组:第i个校验位每次开始选包括它自己的2^(i-1)个位,再间隔2^(i-1)位,然后再选2^(i-1)位,然后再间隔2^(i-1)位……直到选择到串末尾
例如:数据是4位的时候对应的三组校验组为:假设传输的7位为A1 A2 A3 A4 A5 A6 A7, 其中A1 A2 A4为校验位
E1:A1,A3,A5,A7
E2:A2,A3,A6,A7
E3:A4,A5,A6,A7
c>确定是使用奇校验还是偶校验来填写校验位并传输,然后根据校验位进行更正,下面以4位数据位来距离,试判定在奇校验的前提下数据1101011串是否正确,如果不正确确定是哪一位出错:
A1 | A2 | A3 | A4 | A5 | A6 | A7 | 是否有错/有错为1 | |
E1 | 1 | 0 | 0 | 1 | 1 | |||
E2 | 1 | 0 | 1 | 1 | 0 | |||
E3 | 1 | 0 | 1 | 1 | 0 |
注:因为是奇校验而现在1的个数却是偶数,所以第一组出错了
可以看到第一组错了,那么A1,A3,A5,A7有可能错了,但是因为A3,A5,A7在E2和E3组中没有出错,所以就是A1出错了,海明码通过这样的构造可以有神奇的结论,就是错误的位数就是E3,E2,E1构成的二进制数的值,比如这里是001,现在假设如果E3,E2,E1是101的话,可以看到是第一组和第三组错了,这两组共同的有A7,A5,但是第二组中的A7没有错,所以是A5错了,正好是101表示的二进制数。
三、循环冗余码
1、解决的问题:循环冗余校验(Cyclic Redundancy Check)码简称CRC码。它适用于对一个数据块进行校验。常用来对磁表面存储器进行校验,也用于同步串行通信。磁表面存储器的读出错误主要是由于磁表面出现问题:划伤,灰尘,涂层不匀等。由于磁表面存储器的位密度远高于磁道密度,因此一个磁道上连续出错的可能性要较几道同时出错的可能性大得多。这是连续集中出现的错误,称作猝发性错误(Burst Error),和单个的随机性出错不同,因此提出循环冗余校验。
2、原理:
I.循环冗余码是基于模2运算的校验码,首先要说明模2运算。模2运算是以2为模的2进制加减乘除运算。以2为模说明运算不考虑进位和借位。模2运算以记号mod 2表示。模2运算的规则:
a>模2加法(用异或实现)
0+0=0 (mod 2)
0+1=1 (mod 2)
1+0=1 (mod 2)
1+1=0 (mod 2)
b>模2减法(用异或实现)
0 - 0=0 (mod 2)
0 - 1=1 (mod 2)
1 - 0=1 (mod 2)
1 - 1=0 (mod 2)
c>模2乘法
0×0=0 (mod 2)
0×1=0 (mod 2)
1×0=0 (mod 2)
1×1=1 (mod 2)
这里的加也要用模二加法
d>模2除法
它的运算规则是:(1)当被除数(或部分余数)的第1位是“1”,商取1,然后进行mod 2减法,减除数。若第1位是0,商取0,减去0。(所谓部分余数是在除法过程中所得的余数。)(2)当部分余数的位数比除数少一位,则部分余数就是最后的余数。
II.生成多项式G(x)
(1)任意一个2进制数都可用一个多项式表示。
11=1·2^1+1·2^0
101=1·2^2+1·2^0
1001=1·2^3+1·2^0
11011=1·2^4+1·2^3+ 1·2^1+1·2^0
因为CRC码是M(x)[原数据]除以某个选定的多项式后产生的。当选用的多项式满足:
(1)任何一位出错时,余数不为0,
(2)不同位出错使余数不同。
称为生成多项式。生成多项式必须是质因式。
III.如何产生CRC码
1)产生CRC校验位的方法
① 设数据信息代码M(x)是n位的2进制数。
② 将M(x)左移g位,因为生成多项式G(x)是g+1位。——余数一定比生成多项式少至少1位
③ M(x)除以G(x),用mod 2除法。
④ 除法完成后,得到的g位余数就是CRC校验位。
2)CRC码
将校验位(余数)加到数据代码M(x)的后面就构成了n+g位的CRC码。
例 如果M(x)=1001,G(x)=1011。[G(x)是生成多项式] 试计算出校验位,并组成CRC码。
1)因为G(x)=4(位)所以g=3。将M(x)左移3位,移空位补0,得到1001000。
2)进行Mod 2除,1001000÷1011=1010,余数为110,即循环冗余校验位。
3)把余数加到M(x)的后面,得到1001110,此即循环冗余码。
在读出校验时,如果读出校验码无误,那么1001110÷1011,余数应为0。
VI.下面给出知道余数怎么找到哪一位出错,以上面的生成 多项式G(x) = 1011为例,假设数据是A1 A2 A3 A4 A5 A6 A7
总结:当出错时,例如1001110误作1000110,此时1000110÷1011,余数不为0。当继续进行Mod 2除法时余数将循环出现。因此被称为循环冗余码。下式中余数011将循环出现。可看出海明码和循环冗余码编码原理相同,方法不同。循环码在存储和传送过程中若是出现错误,则它除以原生成多项式后余数不等于零。出错位和余数的对应关系,见表3.4。