最近在网上搜索了一下CRC算法,发现网上的算法原理说明都比较晦涩难懂。在这总结一下。其实CRC算法的本质很简单,就是把原始信息当成一个K位的无符号二进制整数P,先把它左移R位,得到一个N位的二进制无符号整数P1,然后把这个数除以一个固定的R+1位的无符号整数G,得到的余数就是CRC码。注意,这个余数的长度一定不会超过R位。把P1和CRC码相加就是一个完整的CRC数据T。校验方法很简单,就是用T除以G,如果余数为0则数据正确。这个原理很简单,就是一个数P1除以某个除数G,得到余数C,那么P1+C一定可以被G整除。
那么,在程序上怎么实现呢?我们都知道在32位的CPU中,除法运算最大支持的位数是64位无符号整数,而我们的原始信息一般都大于64位,所以,这是就需要引入多项式的除法运算。我们都知道一个二进制无符号整数都可以看成是X=2的一个多项式,如:10010101 = 1*2^7 + 0*2^6 + 0*2^5 + 1*2^4 + 0*2^3 + 1*2^2 + 0*2^1 + 1*2^0
那么,我们可以把P1, T, G都当成多项式,根据多项式的除法的演算方法,我们就可以从高到低逐位处理了。如果对多项式除法不了解,下面是多项式的除法的步骤:
(1)把被除式、除式按某个字母作降幂排列,并把所缺的项用零补齐。
(2)用被除式的第一项除以除式的第一项,得商式的第一项。
(3)用商式的第一项去乘除式,把积写在被除式下面(同类项对齐),消去相等项,把不相等的项结合起来。
(4)把减得的差当作新的被除式,再按照上面的方法继续演算,直到余式为零或余式的次数低于除式的次数时为止。被除式=除式×商式+余式
如果一个多项式除以另一个多项式,余式为零,就说这个多项式能被另一个多项式整除。
下面是一个例子:
由于是二进制,多项式的每个系数只能是0或1,x=2,因此在计算机中这个“多项式”的除法要简单得多。实际上,这也是CPU中除法器的工作原理。
另外,因为多项式除法要从高次幂项先计算,所以在网络传输中,一般都是高字节先传输的。下面是各种CRC算法的信息,其中的CRC后面的数字表示R的取值,如CRC-32表示R=32,即校验码长度为32位。其中的简记式即G的简记值,实际的G值需要在简记式的基础上在最高位加一,即加上2^R,将G扩充到R+1位。如CRC-32中,G的取值为0x104C11DB7,CRC-32c中G的取值为0x1EDC6F41 。
名称 |
生成多项式 |