学习boost之0.02 对CRC算法的理解
2014-08-11 01:00
267 查看
之前在看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
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
相关文章推荐
- 我学习CRC32、CRC16、CRC原理和算法的总结(与WINRAR结果一致)
- 对算法的一些学习和理解
- Boost 学习之算法篇 mismatch
- 数据结构与算法学习笔记——二叉树的初步理解
- CRC算法理解
- 学习CRC32、CRC16、CRC原理和算法的总结
- 算法学习笔记之卡尔曼滤波算法理解
- Boost 学习之算法篇 partition_point
- Boost 学习之算法篇 is_permutation
- 【深入理解Java虚拟机】------ 学习0303 垃圾收集算法
- 旧金山大学的算法可视化学习教程 赞的教程,将抽象的算法可视化,易于理解
- 数据挖掘十大经典算法学习之Adaboost自适应增强学习算法
- 我学习CRC32、CRC16、CRC原理和算法的总结(与WINRAR结果一致)
- Boost 学习之算法篇 equal
- Boost 学习之算法篇 one_of 与 one_of_equal
- 匈牙利算法学习 (名词理解 + 简单说明)
- sysgen学习之cordic算法的理解
- Boost 学习之算法篇 any_of 与 any_of_equal
- Boost 学习之算法篇 gather
- 强化学习算法的原理理解