在数据通信中用得最广泛的检错码是一种漏检率低得多也便于实现的循环冗余校验码(CRC,Cyclic Redundancy Check),又称多项式码。这是因为,任何一个由二进制数位串组成的代码都可以和一个只含有0和1两个系数的多项式建立一一对应的关系,一个k位帧可以看成是从Xk-1到X0的k次多项式的系数序列,这个多项式的阶数为k-1,高位(最左边)是Xk-1项的系数,下一位是Xk-2的系数,依次类推。例如,1011011有7位,表示成多项式是X6+X4+X3+X+1;而多项式X5+X4+X2+X对应的位串是110110。
CRC校验的基本思想是利用线性编码理论,在发送端根据要传送一个n比特的帧或报文,发送器生成一个r比特的序列,称为帧检验序列(FCS)。这样所形成的帧将由(n+r)比特组成。这个帧刚好能被某个预先确定的数整除。接收器用相同的数去除外来的帧,如果无余数,则认为无差错。循环冗余校验与奇偶校验不同,后者是一个字符校验一次,而前者是一个数据块校验一次。在同步串行通信中,几乎都使用这种校验方法。例如,对磁盘信息的读/写等。
目前已有多种生成多项式被列入各类通信标准中,欲了解的请进入。
任何一个n位的二进制数都可以用一个n-1次的名项式夹表示。
B(X)=Bn-1X n-1+Bn-2 X n-2+…+B1X1+B0X0
例如,二进制数11000001,可写为B(X)=X7+X6+1。此多项式称为码多项式(或信息多项式)。二进制码多项式的加减运算为模2加减运算,即两个码多项式相加时,对应项系数进行模2加减。所谓模2加减就是各位做不带进位、借位的按位加减。这种加减运算实际上就是逻辑上的异或运算,即加法和减法等价。
B1(X)+B2(X)=B1(X)-B2(X)=B2(X)-B1(X)
二进制码多项式的乘除法运算与普通代数多项式的乘除法运算是一样的,符合同样的规律,如下式。其中,Q(X)为B1(X)除以B2(X)的商,亦称整数多项式,R(X)为余数多项式。若能除尽,则R(X)=0。
B1(X)/B2(X)=Q(X)+R(X)/B2(X)
n位循环码的格式如图1所示。从图1中可以看出,一个n位的循环码是由k位信息位加上r位校验位组成的,其中r= n-k。
图1:n位循环码
通常把这样新组成的二进制位序列叫做循环冗余码(CRC)。表征CRC码的多项式叫生成多项式G(x)。k位二进制数加上r位CRC码后,即信息位要向左移(n-k)位,这相当于B(X)乘以Xr。XrB(X)被生成多项式G(X)除,得整数多项式Q(X)加上余数多项式R(X),即
X rB(X)/G(X)=Q(X)+R(X)/G(X)
移项得
X rB(X)-R(X)=Q(X)G(X)
根据上述的模2加减运算公式,上式可写为
X rB(X)+R(X)=Q(X)G(X)=V(X)
上式说明:信息多项式B(X)和余数多项式R(X)可以合并成一个新的多项式V(X)(称为循环码的码多项式),则该多项式是生成多项式G(X)的整数倍,即能被G(X)整除。根据这一原理,在发送端用信息码多项式B(X)除以生成多项式所得的余数多项式R(X),就是所要加的监督位。将循环码的码多项式V(X)除以生成多项式G(X),若能除尽,说明传送正确,否则说明出差错。下面举例介绍CRC码的计算方法。
由以上分析可知,CRC校验的关键是如何求出余数,此余数即为校验码(CRC校验码)。以前通常用数字电路来实现,而现在可以用计算机来完成。图2所示为CRC校验码生成器和校验器示意图。
从图2中可以看出,CRC校验码的生成和校验基本分三步。首先,在数据单元的末尾加上r个0。r是一个比预定除数(生成多项式G(X))的比特位数(r+l)少1的数。其次,采用二进制除法将新的加长的数据单元(n位)除以除数G(X)。由此除法产生的余数就是CRC校验码。最后,用从第二步得到的r个比特的CRC校验码替换数据单元末尾附加的r个0。如果余数位数小于r,则最左的默认位数为0。如果除法过程根本未产生余数--也就是说,如果原始的数据单元本身就可以被除数整除--那么以r个0作为CRC码替换余数所在的位置。产生的比特模式正好能被除数整除。
到达接收方的数据单元首先到达的是数据,然后是CRC校验码。接收方将整个数据串当做一个整体去除以用来产生循环冗余校验余数的同一个除数G(X)。如果数据串无差错地到达接收方,循环冗余校验器将产生余数0,因此数据单元将通过检验。如果在传输中数据单元被改变,除法将产生非零余数,因此数据单元将通不过检验。
除了正好数据块的比特值是按除数值变化的错误外,循环冗余校验(CRC)将检测出其他所有错误,甚至对于四比特错误--这种情况发生的可能性仍然是很小的。而且,常用的CRC除数通常有17或是33个比特,使得不可检测的错误可能降低到几乎近于零。
循环冗余码生成器采用了模2除法。下面举例说明循环冗余码的生成过程。
例如,在循环冗余校验码系统中,设其生成多项式为G(X)=X4+X3+1,试求出信息序列10110011的CRC循环冗余校验码(要求写出计算步骤),并说明在接收端如何判断传输的正确性。
1)首先把生成多项式转换成二进制数:G(X) = X4+X3+1=11001
2)计算CRC余数,如图3所示。
图3:计算余数的二进制除法
第一步,要在数据位(被除数)后边补0,0的个数比除数(生成多项式)少一位。
第二步,做除法,从被除数的头五位减去五位的除数。除数的每一位都与被除数的对应位在不涉及上一位的情况下独立进行减法(实际进行的是模2加)。在本例中,除数11001与被除数的前五位10110进行的是模2加,得到1111(余数1前面的0被省略)。
在被除数中下一个没有使用过的比特接着被抄录下来,使得余数的位数和除数的位数相同。如果位数不够,在商位补0(这与一般除法相同),因此,下一步就是11110Å11001,结果是111,依次类推。
在二进制除法中,除数总是以1开头的,然后从上一次的被除数/余数中与除数位数相同的部分中减去除数,并且只能从最左位是1的被除数/余数中减去除数。每当被除数/余数的最左位是0时,就在该步骤中把0丢弃,再把被除数中的下一个未使用比特抄录下来填充余数,同时对应的商数位补一个零,并按上述方法进行二进制除法运算,一直重复这个过程直到被除数中所有比特都被使用过。
余数100只有3位,而余数应为4位(比除数少一位),因此,取校验码时应在前面填一个0,故其CRC校验码应为0100,于是可求出该信息码的循环冗余码为101100110100。
为了判断传输的正确性,在接收端要有一个CRC校验器。它的功能和发生器一样,当收到CRC冗余校验码后,做同样的模2除法(注意,这里采用的生成多项式一定要与发送端相同)。如果余数是全0,则说明传输正确;否则,传输错误,应重传。
在上例中,假如收到的数据是101100110100,图4是校验结果。
图4:校验用二进制除法
在串行通信中,生成多项式的选取是提高差错控制能力的关键因素。在使用中,通常使用下列三种生成多项式G(X)来产生CRC校验码。