什么是CRC
CRC(Cyclic Redundancy Check)中文译为循环冗余校验码。CRC被广泛应用于网络数据传输、软件保护等领域。
它是一种根据网络数据数据包或电脑文件等数据产生简短固定位数校验码的一种散列函數,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者存储之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。一般来说,循环冗余校验的值都是32位的整数。由于本函数易于用二进制的电脑硬件使用、容易进行数学分析并且尤其善于检测传输通道干扰引起的错误,因此获得广泛应用。此方是由W. Wesley Peterson于1961年发表。
CRC的特点
CRC的主要特点就是:检错能力极强,开销很小,易于实现。从性能和开销上综合考虑,其远远优于奇偶校验及算术和校验等方式。
CRC的原理
CRC生成基本理论
由于计算机数据在计算机底层的表现为二进制串,所以任何数据都可以看成如下的多项式。
$$ P(x)=a_{n-1}x^{x-1}+a_{n-2}x^{x-2}+\cdots+a_1x+a_0 $$
多项式系数为0或者1,x为伪变量,x的指数表示系数在二进制中排列的位数。例如二进制数据01001001可以表示为如下的多项式:
$$ P(x)=0x^7+1x^6+0x^5+0x^4+1x^3+0x^2+0x^1+1x^0 $$
好叻,我们知道了数据如何表示为多项式了,那么如何得到这个校验码呢?其实是这样的啦:数据P(x)通过除以选定的多项式G(x)得到一个商Q(x)和余数R(x)。这个余数R(x)就是我们的校验码啦。公式表示如下:
$$ P(x)=Q(x)\times G(x)+R(x) $$
通常G(x)为16位或32位,由于P(x)原本的数据位数可能少于R(x),为了得到16位或32位的R(x)我们需要将P(x)扩充到至少16位或32位以上,通常的做法是在P(x)后加上CRC的位数,如果是16位的CRC则需要添加16位,如果是32位则需要添加32位。
如何得到R(x)呢?根据上面公式用P(x)除以G(x)得到的余数就是R(x)了,注意,这里的除法使用的是模2除法。
模2除(按位除)做法与算术除法类似,但每一位除(减)的结果不影响其它位,即不向上一位借位。所以实际上就是异或。然后再移位移位做下一位的模2减。步骤如下:
a、用除数对被除数最高几位做模2减,没有借位。
b、除数右移一位,若余数最高位为1,商为1,并对余数做模2减。若余数最高位为0,商为0,除数继续右移一位。
c、一直做到余数的位数小于除数时,该余数就是最终余数。
举例如下:
假设有8位的数据P(x)为0100 1001(0x49),16位的标准CRC多项式G(x)为1000 0000 0000 0101(0x8005),则得到余数R(x)为0000 0010 1101 1010(0x02DA)
CRC校验基本理论
发送端想要发送数据P(x),接收端在收到数据之后为了校验数据是否损坏需要对接收到的数据进行校验。经过上述CRC生成基本原理我们可以计算得到余数R(x)即为CRC校验码,原始数据P(x)经过扩展后加上校验码R(x)即为发送端发送给接收端的数据:$$ P(x)\times X^r+R(x) $$
接收端接到数据之后,做如下校验:
$$P(x)\times X^r=Q(x)\times G(x)+R(x) $$
$$ \frac{P(x)\times X^r+R(x)}{G(x)}=\frac{Q(x)\times G(x)+R(x)+R(x)}{G(x)}=\frac{Q(x)\times G(x)}{G(x)}=Q(x)$$
注意:由于是模2除(模2减),所以R(x)+R(x)=0
很明显如果信息传输的过程中没有发生错误,则接收到的数据信息多项式$$P(x)\times X^r+R(x)$$一定可以被生成多项式(G(x))整除,这就是CRC的检错原理。
但是这一命题的逆命题并不成立,也就是说接收到的信息多项式可以被生成多项式整除,并不代表信息在传输中没有发生错误。
CRC的检错能力
- CRC校验码能检查出全部单个错
- CRC校验码能检查出全部离散的二位错
- CRC校验码能检查出全部奇数个错
- CRC校验码能检查出全部长度小于或等于K位的突发错
- CRC校验码能以[1-(1/2)K-1]的概率检查出长度为(K+1)位的突发错
例如,如果K=16,CRC校验码能检查出小于或等于16位的所有突发错,并能以99.997%的概率检查出长度为17位的突发错,漏检的概率为0.003%。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。