在数据存储和数据通讯领域,为了保证数据的正确,就不得不采用检错的手段。在诸多检错手段中,CRC是最著名的一种。CRC的全称是循环冗余校验。 为了方便理解CRC原理, 我们这里先介绍一种简单的错误检测方法:校验和。
待发送的消息 : 6 23 4
带校验和的消息 : 6 23 4 33
接受端收到的消息 : 6 27 4 33
这种方式下,我们在接收端计算校验值为6+27+4 = 37, 而校验和中校验码为33.37!=33, 因此可以判定发送数据在传输过程中受到了破坏。
这种简单的校验办法, 有一定作用,但存在一个缺陷:校验成功,不代表数据没有变化。例如假设接受到的数据为8 21 4 33
8+21+4 =33 ,与消息体中校验码一致,校验通过。但数据显然是与发送端原始数据不一致的。
本文介绍的CRC校验,比这种方法要准确和先进的。
CRC校验是从数据本身进行检查,它依靠某种数学上约定的形式进行检查,校验的结果是可靠或不可靠,如果可靠就对数据进行处理,如果不可靠,就丢弃重发或者进行修复。
CRC的基本原理就是:把待发送的数据当作一个二进制数,并且给它生成一个校验码。该校验码是该二进制数与另一个约定的数字的余数。
例如: 数据 (6,23)被当成两个字节的数据,其对应二进制数为0000-0110-0001-0111;(相当于10进制153)
假设我们校验寄存器为1个字节宽,并且校验寄存器里的值为常量1001.(相当于10进制9)
校验值可以这么算出来:1559/9 = 173...2.余数为2,即二进制0010,16进制02.
那么我们可以使用4比特的该校验值传输数据(06172),其中0617是原始数据,2是校验码。在接收端,可通过钱16位数据0617除以2,计算出余数。并把该余数与读出来的校验码2作比较。如果相等,校验通过,书名数据传输是正确的。否则,数据传输就是错误的。
下面我们以日常使用来更深入的探讨其原理。
由前面讨论可知, CRC码是由两部分组成,前部分是信息码,就是需要校验的信息,后部分是校验码,如果CRC码共长n个bit,信息码长k个bit,就称为(n,k)码。它的编码规则是:
1、首先将原信息码(kbit)左移r位( k+r=n )
2、运用一个生成多项式g(x)(也可看成二进制数)用模2除上面的式子,得到的余数就是校验码。
非常简单,要说明的:模2除就是在除的过程中用模2加,模2加实际上就是我们熟悉的异或运算,就是加法不考虑进位,公式是:
0+0=1+1=0,1+0=0+1=1
0 + 0 = 0 0 - 0 = 0
0 + 1 = 1 0 - 1 = 1
1 + 0 = 1 1 - 0 = 1
1 + 1 = 0 1 - 1 = 0
显然,加和减是一样的效果, 都等同于异或运算。
即‘异’则真,‘非异’则假。
由此得到定理:a+b+b=a 也就是‘模2减’和‘模2加’真值表完全相同。
有了加减法就可以用来定义模2除法,于是就可以用生成多项式g(x)生成CRC校验码。
例如: g(x)=x4+x3+x2+1,(7,3)码,
校验码的计算:
11101 | 110,0000(设a=11101 ,b=1100000)
取b的前5位11000跟a异或得到101
101加上b没有取到的00得到10100
然后跟a异或得到01001
也就是余数1001
101
11101 | 110,0000
111 01
1 0100
1 1101
1001
余数是1001,所以CRC码是110,1001
如何选择生成多项式?
------------------
很明显,不同的生成多项式,其检错能力是不同的。如何选择一个好的生成多项式需要一定
的数学理论,这里只从一些侧面作些分析。显然,要使用r位校验码,生成多项式的次数应为
r。生成多项式应该包含项"1",否则校验码的LSB(Least Significant Bit)将始终为0。如果
消息(包括校验码)T在传输过程中产生了差错,则接收端收到的消息可以表示为T + E。若E不
能被生成多项式G除尽,则该差错可以被检测出。
以下是一些标准的CRC算法的生成多项式:
标准 多项式 16进制表示
---------------------------------------------------------------------------
CRC12 x^12 + x^11 + x^3 + x^2 + x + 1 80F
CRC16 x^16 + x^15 + x^2 + 1 8005
CRC16-CCITT x^16 + x^12 + x^5 + 1 1021
CRC32 x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 04C11DB7
+ x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
16进制表示去掉了最高次项,CCITT在1993年改名为ITU-T。CRC12用于6位字节,其它用于8位
字节。CRC16在IBM的BISYNCH通信标准。CRC16-CCITT被广泛用于XMODEM, X.25和SDLC等通信
协议。而以太网和FDDI则使用CRC32,它也被用在ZIP,RAR等文件压缩中。在这些生成多项式
中,CRC32是原始的,而其它3个都含有因子x + 1。 |