CRC32算法详细推导(2)

From: http://blog.csdn.net/sparkliang/article/details/5671977

CRC算法详解(2)

初见 Table-Driven

 

变换到上面的方法后,我们离 table-driven 的方法只有一步之遥了,我们知道一个字节能表示的正整数范围是 0~255,步骤 1 中的计算就是针对 reg 的高 Byte 位进行的,于是可以被提取出来,预先计算并存储到一个有 256 项的表中,于是下面的算法就出炉了,这个和上面的算法本质上并没有什么区别。

[cpp] view plaincopy
  1. #define POLY 0x04C11DB7L // CRC32生成多项式  
  2. static unsigned int crc_table[256];  
  3. unsigned int get_sum_poly(unsigned char data)  
  4. {  
  5.     unsigned int sum_poly = data;  
  6.     sum_poly <<= 24;  
  7.     for(int j = 0; j < 8; j++)  
  8.     {  
  9.         int hi = sum_poly&0x80000000; // 取得reg的最高位  
  10.         sum_poly <<= 1;  
  11.         if(hi) sum_poly = sum_poly^POLY;  
  12.     }  
  13.     return sum_poly;  
  14. }  
  15. void create_crc_table()  
  16. {  
  17.     for(int i = 0; i < 256; i++)  
  18.     {  
  19.         crc_table[i] = get_sum_poly(i&0xFF);  
  20.     }  
  21. }  
  22. // 以byte数据为例  
  23. unsigned int CRC32_3(unsigned int data)  
  24. {  
  25.     unsigned char p[8];  
  26.     memset(p, 0, sizeof(p));  
  27.     memcpy(p, &data, 4);  
  28.     unsigned int reg = 0, sum_poly = 0;  
  29.     for(int i = 0; i < 8; i++)  
  30.     {  
  31.         // 计算步骤1  
  32.         sum_poly = crc_table[(reg>>24)&0xFF];  
  33.         // 计算步骤2  
  34.         reg = (reg<<8)|p[i];  
  35.         reg = reg ^ sum_poly;  
  36.     }  
  37.     return reg;  
  38. }  

更进一步

 

上面的这个算法已经是一个Table-Driven的CRC-32算法了,但是实际上我们看到的CRC校验代码都是如下的形式:<div><div><div style="color:silver;"><strong>[cpp]</strong> <a target=_blank href="http://blog.csdn.net/sparkliang/article/details/5671977#" title="view plain" style="color:rgb(160, 160, 160);">view plain</a><a target=_blank href="http://blog.csdn.net/sparkliang/article/details/5671977#" title="copy" style="color:rgb(160, 160, 160);">copy</a></div></div><ol start="1" style="color:rgb(92, 92, 92);"><li style="color:inherit;"><span style="color:black;">r=0;  </span></li><li><span style="color:black;"><span style="color:rgb(0, 102, 153);">while</span>(len--)  </span></li><li style="color:inherit;"><span style="color:black;">     r = (r<<8) ^ t[(r >> 24) ^ *p++];  </span></li></ol></div> 

下面我们将看看是做了什么转化而做到这一点的。

 

 

首先上述 CRC 算法中,我们需要为原始数据追加 r/8Byte 个 0 , CRC-32 就是 4Byte 。或者我们可以再计算原始数据之后,把 0 放在后面单独计算,像这样:

[cpp] view plaincopy
  1. // 先计算原始数据  
  2. for(int i = 0; i < len; i++)  
  3. {  
  4.         sum_poly = crc_table[(reg>>24)&0xFF];  
  5.         reg = (reg<<8)|p[i];  
  6.         reg = reg ^ sum_poly;  
  7. }  
  8. // 再计算追加的4Byte 0  
  9. for(int i = 0; i < 4; i++)  
  10. {  
  11.         reg = (reg<<8) ^ crc_table[(reg>>24)&0xFF];  
  12. }  

这看起来已经足够好了,而事实上我们可以继续向下进行以免去为了附加的 0 而进行计算。在上面算法中,最后的 4 次循环是为了将输入数据的最后 r/8 位都移出 reg ,因为 0 对 reg 的值并没有丝毫影响。

对于 CRC-32 ,对于任何输入数据 Dn...D8…D5D4…D1 ,第一个 for 循环将 Dn…D8…D5 都依次移入,执行XOR 运算再移出 reg ;并将 D4…D1 都移入了 reg ,但是并未移出;因此最后的 4 次循环是为了将 D4…D1 都移出 reg 。

Di 与 Ri 执行 XOR 运算后值将会更新,设更新后的值表示为 Di’ ,不论执行了多少次 XOR 运算。

如果 reg 初始值是 0 ,那么第一个 for 循环中开始的 4 次循环干的事情就是,把 Dn…Dn-3 移入到 reg 中(与0 做 XOR 结果不变),执行 4 次后 reg 的值就是 Dn.Dn-1.Dn-2.Dn-3 ;

第 5 次循环的结果就是: reg = crc_table[Dn] ^ Dn-1.Dn-2.Dn-3.Dn-4 ;

第 6 次循环的结果就是: reg = crc_table[Dn-1’] ^ Dn-2’.Dn-3’.Dn-4 ; Dn 移出 reg 。

因此上面的计算可以分为 3 个阶段:

1 )前 4 次循环,将 Dn.Dn-1.Dn-2.Dn-3 装入 reg ;

2 )中间的 n-4 次循环,依次将 Di 移入 reg ,在随后的 4 次循环中,依次计算 Di+4 , Di+3 , Di+2 和 Di+1对 Di 的影响;最后移出 reg ;  

3 )最后的 4 次循环,实际上是为了计算 D4 , D3 , D2 和 D1 都能执行第 2 步的过程;

具体考察 Di :

1 ) Di 移入到 reg 中, R1=Di ,接着与 crc_table[R4] 执行 XOR 运算;

2 )循环 4 次后, Di 成为 reg 的最高位 R4 ,并且因为受到了 Dn…Di+1 的影响而更新为 Di’ ;

上面的运算步骤如下面所示,其中 F 是对应得 crc_table[R] 的值。

可以清晰的看到,最后 reg 的高 Byte 是 Di 和 F 之间一次次 XOR 运算的结果。依然根据 XOR 运算的结合律,我们可以分两步走:

1)  先执行 F 之间的 XOR 运算,设结果为 FF ,它就是 reg 的首字节;

2)  然后再直接将 Di 和 FF 进行 XOR 运算,并根据结果查 CRC 表;

3)  计算出 XOR 运算后, Di…Di-3 已经移入 reg ;因此再将查表结果和 (reg<<8) 执行 XOR 运算即可;

这就是方法 2 ,于是我们的 table-driven 的 CRC-32 校验算法就可以写成如下的方式了:

[cpp] view plaincopy
  1. reg = 0;  
  2. for(int i = 0; i < len; i++)  
  3. {  
  4.     reg = (reg<<8) ^ crc_table[(reg>>24)&0xFF ^ p[i]];  
  5. }  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/404154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS UIWebView加载网页、文件、HTML

UIWebView是用来加载加载网页数据的一个框架.UIWebView可以用来加载pdf,word,doc,等等文件,生成webview 有两种方法&#xff0c;1、通过storyboard 拖拽 2、通过alloc init 来初始化创建webview&#xff0c;下列文本中 _webView.dataDetectorTypes UIDataDetectorTypeAll; 是识…

nginx的upstream模块安装

下载连接&#xff1a;wget http://code.google.com/p/nginx-upstream-jvm-route/downloads/detail?namenginx-upstream-jvm-route-0.2.tar.gz&can1&q/nginx-upstream-jvm-route-0.2.tar.gz nginx_upstream_jvm_route 是一个 Nginx 的扩展模块&#xff0c;用来实现基于…

前端面试题Vue-cli目录汇总

【Vue-cli】 [vue-cli]vue-cli3你有使用过吗&#xff1f;它和2.x版本有什么区别&#xff1f; [vue-cli]vue-cli默认是单页面的&#xff0c;那要弄成多页面该怎么办呢 [vue-cli]不用vue-cli&#xff0c;你自己有搭建过vue的开发环境吗&#xff1f;流程是什么&#xff1f; [v…

CRC32算法详细推导(3)

From:http://blog.csdn.net/sparkliang/article/details/5671543 CRC32算法详细推导&#xff08;3&#xff09; 郁闷的位逆转 看起来我们已经得到 CRC-32 算法的最终形式了&#xff0c;可是、可是在实际的应用中&#xff0c;数据传输时是低位先行的&#xff1b;对于一个字节 …

WebService的学习

这篇文章不错&#xff0c;直接转了 http://blog.csdn.net/terryzero/article/details/5976638#comments 转载于:https://www.cnblogs.com/zhilu-doc/p/5291927.html

linux 用户行为审计

根据公司需求&#xff0c;整理了一个linux用户审计的脚本&#xff0c;现和大家分享&#xff01; 具体步骤如下&#xff1a; 一&#xff1a;配置调试 1.创建用户审计文件存放目录和审计日志文件 &#xff1b; mkdir -p /var/log/usermonitor/ 2.创建用户审计日志文件&#xff1…

前端面试题vue-element汇总

【Vue-element】 [vue-element] ElementUI是怎么做表单验证的&#xff1f;在循环里对每个input验证怎么做呢&#xff1f; [vue-element] 你有二次封装过ElementUI组件吗&#xff1f; [vue-element] ElementUI怎么修改组件的默认样式&#xff1f; [vue-element]ElementUI的穿…

每天一点Swift(五)控制器的生命周期和SizeClass

字数358 阅读19 评论0 喜欢0 初始化init-->awakeFromNib--> prepare a segue --> SB去设置outlets --> viewDidLoad 1. viewDidLoad 在viewDidLoad中&#xff0c;outlets已经被设置&#xff1b;但是几何位置&#xff08;bounds&#xff09;并没有被设置 viewDidLoa…

h264 I帧的判断

From:http://blog.csdn.net/dxpqxb/article/details/13289205 H264数据的NALU 头的格式如图2 所示&#xff1a; F&#xff1a;forbidden_zero_bit.1 位&#xff0c;如果有语法冲突&#xff0c;则为 1。当网络识别此单元存在比特错误时&#xff0c;可将其设为 1&#xff0c;以便…

前端面试题node.js汇总

【NodeJs】 [NodeJs] 你有使用过npx吗&#xff1f;它主要解决什么问题&#xff1f; [NodeJs] 如何使用nodejs对base64进行编解码&#xff1f; [NodeJs] npm提供了哪些钩子&#xff1f;各有什么作用&#xff1f; [NodeJs] 如果发现node_modules中有个模块代码有bug&#xff…

win10 下安装、配置、启动mysql

1、下载http://dev.mysql.com/downloads/mysql/ 2、Community > MySQL Community Server 3、Other Downloads: > Windows (x86, 32-bit), ZIP Archive 5、解压mysql-5.7.11-winx64.zip&#xff0c;解压在 D:\soft\mysql-5.7.11-winx64\mysql-5.7.11-winx64 6、在D:\soft\…

成功驱动HD4600-Clover引导

本人机器配置如下&#xff1a; 操作系统 Windows 7 旗舰版 64位 SP1 ( DirectX 11 ) 处理器 英特尔 Core i7-4770K 3.50GHz 四核 核显&#xff1a; Intel HD4600 主板 华硕 Z87-PRO (英特尔 Haswell) 内存 8 GB ( 金士顿 DDR3 1778MH…

前端软技能面试汇总

【软技能】 [软技能] 在前后端分离项目里&#xff0c;请说说前端传递的token的流程&#xff1f; [软技能] 现如今面对如层出不穷的类库&#xff0c;说说你的感受 [软技能] 你认为计算专业和非计算机专业的差别在哪&#xff1f;为什么&#xff1f; [软技能] png-8和png-24有…

ACM训练计划(上)

一.基本算法: (1)枚举.(poj1753,poj2965) (2)贪心.(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(poj3295) (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法: (1)图的深度优先遍历和广度优先遍历. (2)最短路…

单硬盘上mac + win7双系统,GUID-GPT分区

首先&#xff0c;当然要介绍下我的环境了。 一、环境介绍 1. 主板是支持UEFI启动的&#xff0c;但是我感觉自己没用到。 2. 我有两个硬盘: hd0: 准备安装mac和win7_x64 hd1: GUID格式&#xff0c;GPT分区&#xff0c;已装有mac10.9.3环境&#xff0c;还有个FAT32的分区&a…

React开发(273):异步调用的方式

1、回调函数方式 doFirstThing((err, data) > {if (err) {console.log(err);return;}doSecondThing(data, function(err, data){if (err) {console.log(err);return;}doThirdThing(data, function(err, data){if (err) {console.log(err);return;}})}) })2、Promise 方式 …

hdu 1166 敌兵布阵 (线段树)

http://acm.hdu.edu.cn/showproblem.php?pid1166最基础的线段树&#xff0c;单点更新。完全跟着HH的代码风格写的。code:#include<cstdio>#define lson l, m, rt<<1#define rson m1, r, rt<<1|1const int maxn 50005 ;int sum[maxn<<2] ;void PushUp…

将clover安装到硬盘EFI分区, 解决root device uuid is ...问题

其实说白了&#xff0c;很简单&#xff0c;照着配置图来&#xff0c;一招搞定&#xff0c;但是当你不知道这些配置的时候&#xff0c;将可能耗费你好几天的时间&#xff0c;而且还不一定得到最优解。 附“Clover v2k r2703.pkg"下载地址: http://download.csdn.net/deta…

IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) C. Bear and Up-Down 暴力

C. Bear and Up-Down题目连接&#xff1a; http://www.codeforces.com/contest/653/problem/C Description The life goes up and down, just like nice sequences. Sequence t1, t2, ..., tn is called nice if the following two conditions are satisfied: ti < ti …