学习boost之0.02 对CRC算法的理解

来源:互联网 发布:送女朋友生日礼物知乎 编辑:程序博客网 时间:2024/06/05 19:16

    之前在看CRC算法的表驱动原理,一直没搞懂,然后自己按照文章里的说法在纸上重写了一遍,豁然开朗。很多算法以为高深,直到自己也会了之后。

    CRC翻译为循环冗余校验,算法的本质是企图校验数据差错,保证数据的正确和完整性。在数学描述上就是简单的求余,把要校验的字符串当作一个长整数,挑选一个合适除数,相除的余数就是CRC值。如果真的用数学上的除法,会导致位之间强关联,后来用mod2除法,弥补这一缺陷。对CRC介绍的很全面的文章参见文后给的参考资料。

举个例子:

字符串(被除数)A: 11001010 01101001

除数B:   110111010(宽为8位)

 A/B 

                       ----------------------------------------------------

  110111010)    11001010 1101001

                         11011101 0  ------>(1)

                        -----------------------------------

                               10111 0110

                               11011 1010-------->(2)

                            --------------------------------------

                                 1100 11001

                                 1101 11010 ----->(3)

                                ------------------------------------

                                       1 00011001

                                       1 10111010 -------(4)

                                -------------------------------------

                                          10100011 ------>(5)

(5)即为CRC值。这是最原始的计算方法,后来发现有更高效的算法,就是以字节为单位进行计算。

我们重新看看上面的计算过程。考虑下面的式子


                       ----------------------------------------------------

  110111010) 11001010 00000000

                         11011101 0  ------>(1*)

                            -----------------------------------

                               10111 00000000

                               11011 1010-------->(2*)

                            --------------------------------------

                                  1100 10100

                                  1101 11010 ----->(3*)

                                ------------------------------------

                                         1 01110000

                                         1 10111010 -------(4*)

                                -------------------------------------

                                            11001010 ------>(5*)

可以看到如果只计算一个字节,可得到式子(5*)。

我们再把他与第二字节异或(mod2除法),

01101001

11001010

-----------------

10100011  -----------------(6*)

结果跟上面的(5)式一模一样有木有。这不是偶然而是异或有这个特性:a XOR b XOR c = a XOR (b XOR c) (6)

对应上面的例子A=11001010 01101001 B=110111010 令A1=00000000 01101001,A2= 11001010 00000000  ,则有A=A1 XOR A2。 于是根据(6)得

     A XOR B = A1 XOR A2 XOR B  = A1 XOR (A2 XOR B)。

于是,我们可以预先计算每个字节对应的(5*)。这样只要根据A2得到预先计算的表索引,查表得到值然后跟A1异或即可完成这一字节的计算。

这就是CRC的表驱动算法,目前所有的CRC实现都是基于这一思想。


参考资料:

1.http://www.ross.net/crc/download/crc_v3.txt

2. http://www.cnblogs.com/FPGA_DSP/archive/2010/05/08/1730529.html

0 0
原创粉丝点击