轻松理解CRC差错检测算法(A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS)七

9 一个表驱动的实现
上面说的“SIMPLE”算法是一个很好的开始,因为它与目前描述的理论直接对应,因为它是如此简单。然而,因为它在位级别进行操作,所以编码实现起来很尴尬(即使是用C语言),执行起来效率也不高(每一位它都要循环一次)。为了让它快起来,我们需要找到一个可以使算法以比位更大的单元来处理信息的方法。可以选的单元有4位,字节(8位),字(16位),和长字(32位),和任何我们所能达到的更大的单元。这当中,4位的最好别用,因为它与字节的边界冲突。所以至少,任何实现加速的算法应该能让我们在字节边界上进行,实事上大多数的表驱动算法一次处理一个字节。
为了方便讨论,让我们从4位的多项式转向32位的。我们的寄存器看起来是一个样的,除了小盒子代表字节而非位,多项式是33位的(一个的隐性位在最高,外加32个“活动”位)(W=32)。
这里写图片描述
“SIMPLE”算法依然是可用的。让我们看下它都做了什么。假设“简单”算法是在全摆中,把32位中的最高的8位(第3字节),设为以下值:
t7 t6 t5 t4 t3 t2 t1 t0
在“简单”算法的下次迭代中,t7将会决定多项式是否与寄存器中整个值相异或。如果t7=1,这就会发生,反之就不会发生。假设多项式的最高的8位是g7 g6 … g0,然后,在下次迭代之后,最高的8位将会是
t6 t5 t4 t3 t2 t1 t0 ?? + t7 * (g7 g6 g5 g4 g3 g2 g1 g0)
[提醒: +代表异或]
新的最高位(将会决定下次迭代发生什么)现在的值是t6 + t7 * g7。千万要注意到,从信息的观点来看,计算新的最高位的所需要的信息已经包含在了原来的最高2位里面。类似的,下一个最高位可以从t7 t6 t5提前计算出。事实上,一般,k次以后的迭代的最高位的值,可以由寄存器的最高k位计算得到。记我们把这个暂时作为定理记下。
设想一下,我们使用寄存器中的最高8位来计算 此后8次迭代后的寄存器中的最高位。假设,我们以计算好的值(我们可以把它存入一个单字节寄存器中,每次出栈一个位来用)去驱动以后8次的迭代。那么,我们注意到3个事情:
*寄存器的最高位没有什么用。不管多少次,在第几个偏移位上,多项式和高8位相异或,它们都会在下8次迭代中被移出(这里原谅是shifted out the right hand side,个人觉得应该是Left)。
*余下的字节将会向左移动一个位置,最右边的字节会移入下一个字节。 而且
*当这进行中时,寄存器会被根据提前计算出的控制字节进行异或操作。
现在,考虑在不同的偏移处对一个常数进行异或操作的效果。如:
0100010 寄存器
…0110与它异或
..0110. 与它异或
0110… 与它异或
_ _
0011000
这个例子的意义是,把一系列常数接连和寄存器值异或,最后的结果是,会存在这样一个值,和最开始的寄存器中的值相异或后,得到与前者相同的结果。
也许你现在已经看到解决方案了。把所有的片段合在一起,我们有了这样的算法。
while(附加后的信息还有字节) {
开始
检查寄存器的首字节。
通过寄存器的首字节计算出控制字节。
把将要在各个偏处,由据控制字节控制,将与寄存器进行异或的poly,相加。
将寄存器左移一个字节,在寄存器的最右字节中读入一个新的信息字节。
把poly和与寄存器相异或。
}
如所见,这并不比“简单”算法好多少。但是,结果是,其中的大部分计算都可以重新计算,装入一个表中。结果就是,上面的算法可以缩减如下:
while(附加后的信息还有字节){
开始
Top = top_byte(Register);
Register = (Register << 24) | 下一个信息字节;
Register = Register XOR precomputed_table[Top];
}
就是这了。如果你明白了这点,你就已经抓住了表驱动CRC算法的核心了。以上是一个非常高效的算法,只需要一个移位,取或,取异或,查找各字节的索引表。以图表来表达,它看起来是这样子:
这里写图片描述
在C语言中,主循环应该是这样的:

r=0;
while (len--)
{
byte t = (r >> 24) & 0xFF;
r = (r << 8) | *p++;
r^=table[t];
}

其中,len是附加后的信息长度,以字节为单位,p指向附加0后的信息,r是寄存器,t是临时变量,表是计算表。这段代码可以更难懂的方式写成如下形式:
r=0; while (len--) r = ((r << 8) | *p++) ^ t[(r >> 24) & 0xFF];
这是一个非常干净,高效的循环,尽管对于一般没有CRC理论基础的观察者来说是太浅显易懂。我们称呼这个为TABLE算法。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值