随笔——USB的CRC算法

   

USB说明书中列举了两种生成多项式(generator polynomials)即除数多项式:一种是针对令牌包(tokens)的x5+x2+1,另一种是针对数据包的x16+x15+x2+1,由于余数要永远比除数小一阶的缘故,所以令牌(tokensCRC5bit组合,数据CRC16bit组合。

两种CRC计算方法一样,步骤如下:

步骤一:创建被除数:

D(x) = xdF(x) + xkL(x)

其中D(x)是待创建的被除数多项式,d表示生成多项式即除数多项式的阶数(令牌包为5,数据包为16),F(x)为待检验的数据流(如令牌包检验中地址位和端口位组合的11位数据),是一个k-1阶多项式,k为数据流位数(如令牌包检验中k11),L(x)表示系数为全1d-1阶多项式(如令牌包检验中L(x)x4+x3+x2+x+1)。

注意:F(x)必须是待检验的数据流由低位到高位顺序排列的(由USB低位到高位发送顺序决定)。如:对于addr 0x70, endpoint 4CRC5,其F(x)流为00001110010,算的时候用该数据流左移5位即得0000111001000000然后加上xkLx)即1111100000000000得到D(x)。而对于数据包0x00 0x01 0x02 0x03CRC16,其F(x)流为00000000100000000100000011000000

步骤二:用生成多项式除“被除数”得到“余数”:

因为这里算法是一个简单的2模运算,不包含进位借位的,所以该除法可表示成简单的异或运算加位移运算。如对于CRC5的校验,D(x)是一个16bit二进制,生成多项式G(x)x5+x2+1,可表示成100101,是一个6bit二进制。除法步骤如下:

1)D(x)的高6位与G(x)异或运算;得到一个新的D'(x)

2)D'(x)左移一位,移掉MSB位,但右边不进位,即此时剩余15bit二进制,称为D''(x)

3)D''(x)的高6位再与G(x)异或运算,然后再左移... ...重复前两步骤,直到D(x)LSB 

      位(最低位)也参与异或运算,此时得到一个4(d-1)多项式的余数R(x)

步骤三:对余数按位取反:

    将得到的(d-1bit二进制余数按位取反(即R(x)+L(x)运算),即可得到最终的CRC

你可能感兴趣的:(算法)