这个算法是在逐BYTE法的基础上进行修改的,在上一篇文章里我们说过,如果不查表的话,逐BYTE法和逐BIT法没什么区别,现在我们就把这个算法写出来,注意在调用CRC校验函数前需要先调用表生成函数:

  1. u32 CRC_Table[];
  2.  
  3. /*******************************CRC校验程序***********************************/
  4. //作者 Skystalker
  5. //输入32位
  6. //多项式,省略最高位1 0x4C11DB7 CCITT-32: 0x04C11DB7 = x32 + x26 + x23 + x22 + x16 + x12 +
  7. // x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
  8. //数据不revert 结果不revert
  9. //初值0x00000000或0xFFFFFFFF,其实所谓的初值就是原始数据要不要跟0xFFFFFFFF先异或先放到Reg中计算,用0xFFFFFFFF只是为了让别人不
  10. //会一下就看出生成多项式是多少
  11. //结果不异或
  12. //验证网址:http://www.zorc.breitbandkatze.de/crc.html
  13. //算法中数据向左移动,相对手工计算等效于生成多项式向右移动,所以不需要在后面加一大堆0
  14. u32 CRC_Check_Software(u8 *ucpData,u8 Length)
  15. {
  16. u32 Reg;//CRC寄存器,即传统除法中的余数
  17. u32 tempbyte=;
  18. u8 i;
  19. u8 count;
  20. u8 j=;
  21. u8 u32DataLen=((Length/)>)?((Length/)+):(Length/);
  22. u32 uipData[]={};
  23. //把byte组合成32位一组的数据放入uipData
  24. ;i<Length;i++)
  25. {
  26. uipData[i/]|=((u32)(*(ucpData+i)))<<(*(j-));
  27. j--;
  28. )
  29. {
  30. j=;
  31. }
  32. }
  33. //以下是算法开始
  34. //查表法
  35. ;count<u32DataLen;count++)
  36. {
  37. Reg=uipData[count];
  38. //Reg^=0xffffffff;//如果初值为0x00000000就把这行注释掉,否则不要注释
  39. ;i<;i++)
  40. {
  41. tempbyte=CRC_Table[(u8)(( Reg >> ) & 0xff)]; //取一个字节,查表
  42. Reg=Reg<<; //丢掉计算过的头一个BYTE
  43. Reg^=tempbyte; //与前一个BYTE的计算结果异或
  44. }
  45. }
  46.  
  47. //查表法
  48. return Reg;
  49. }
  50.  
  51. /***********************************单字节32位CRC校验表生成函数*******************************/
  52. //作者 Skystalker
  53. //多项式,省略最高位1 0x4C11DB7 CCITT-32: 0x04C11DB7 = x32 + x26 + x23 + x22 + x16 + x12 +
  54. // x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
  55. //数据不revert 结果不revert
  56. //结果不异或
  57. //算法中数据向左移动,相对手工计算等效于生成多项式向右移动,所以不需要在后面加一大堆0
  58. void CreateCRCTable(void)
  59. {
  60. u16 Data,j;
  61. u32 tempbyte;
  62. u32 poly=0x4C11DB7; //生成多项式
  63. ;Data<;Data++)
  64. {
  65. tempbyte=((u32)Data)<<;
  66. ;j<;j++)
  67. {
  68. if(tempbyte&0x80000000)
  69. {
  70. tempbyte=tempbyte<<; //要异或时Reg的最高位是1,CRC多项式最高位一直就是1,异或后必为0,所以一开始就偷懒把CRC多项式去掉最高位变成
  71. //0x4C11DB7 ,所以相应的这时候要把Reg左移一位,只要异或后边的32位
  72. tempbyte^=poly;
  73. }
  74. else
  75. {
  76. tempbyte=tempbyte<<;
  77. }
  78. }
  79. CRC_Table[Data]=tempbyte;
  80. }
  81. }

上面的算法每次初始化都要计算一次表,何不直接把表做出来放到程序里:

以下程序在VS2008调试通过,使用时在工程目录里新建一个文件a.c ,运行一遍下面的程序,在a.c 里就有可以直接使用的驱动表:

  1. #include <stdio.h>
  2. #include <windows.h>
  3.  
  4. UINT CRC_Table[];
  5.  
  6. void CreateCRCTable(void)
  7. {
  8. FILE * fp;
  9. unsigned __int16 Data,j;
  10. UINT tempbyte;
  11. UINT poly=0x4C11DB7; //生成多项式
  12. if((fp=fopen("a.c","w"))==NULL)
  13. {
  14. printf("error\n");
  15. }
  16. fprintf(fp,"%s\n","UINT CRC_Table[256]=");
  17. fprintf(fp,"%c\n",'{');
  18.  
  19. ;Data<;Data++)
  20. {
  21. tempbyte=((UINT)Data)<<;
  22. ;j<;j++)
  23. {
  24. if(tempbyte&0x80000000)
  25. {
  26. tempbyte=tempbyte<<; //要异或时Reg的最高位是1,CRC多项式最高位一直就是1,异或后必为0,所以一开始就偷懒把CRC多项式去掉最高位变成
  27. //0x4C11DB7 ,所以相应的这时候要把Reg左移一位,只要异或后边的32位
  28. tempbyte^=poly;
  29. }
  30. else
  31. {
  32. tempbyte=tempbyte<<;
  33. }
  34. }
  35. CRC_Table[Data]=tempbyte;
  36. )
  37. fprintf(fp,"%s%x\n","0x",CRC_Table[Data]);
  38. else
  39. fprintf(fp,"%s%x%c","0x",CRC_Table[Data],',');
  40.  
  41. }
  42. fprintf(fp,"%s\n","};");
  43. }
  44.  
  45. int main()
  46. {
  47. CreateCRCTable();
  48. return TRUE;
  49. }

最简单的CRC32源码-查表法的更多相关文章

  1. 最简单的CRC32源码---逐BIT法

    CRC其实也就那么回事,却在网上被传得神乎其神.单纯从使用角度来说,只需要搞明白模二除法,再理解一些偷懒优化的技巧,就能写出自己的CRC校验程序. 下面的代码完全是模拟手算过程的,效率是最低的,发出来 ...

  2. 最简单的CRC32源码-逐BYTE法

    从按BIT计算转到按BYTE计算,要利用异或的一个性质,具体见前面的文章<再探CRC >. 其实方法跟逐BIT法是一样的,我们只是利用异或的性质,把数据分成一BYTE一BYTE来计算,一B ...

  3. C#,Java,C -循环冗余检验:CRC-16-CCITT查表法

    C#代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...

  4. 嵌入式C语言查表法的项目应用

    嵌入式C实战项目开发技巧:如果对一个有规律的数组表进行位移操作 就像下面的这个表 之前写过上面这个标题的一篇文章,讲的是以位移的方式去遍历表中的数据,效率非常高,但是,如果要实现一个乱序的流水灯或者跑 ...

  5. 嵌入式C语言查表法

    转自:https://blog.csdn.net/morixinguan/article/details/51799668    作者:Engineer-Bruce_Yang 就像下面的这个表 之前写 ...

  6. 经典算法,yuv与rgb互转,查表法,让你的软件飞起来

    代码的运算速度取决于以下几个方面 1. 算法本身的复杂度,比如MPEG比JPEG复杂,JPEG比BMP图片的编码复杂. 2. CPU自身的速度和设计架构 3. CPU的总线带宽 4. 您自己代码的写法 ...

  7. 【C语言学习笔记】空间换时间,查表法的经典例子!知识就是这么学到的~

    我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移植性那些角度. 在我们嵌入式中,我们需要根据实际资源的情况来设计我们的代码.比如当我们能用 ...

  8. YUV420查表法高效、无失真的转换为RGB32格式

    YUV格式有两大类:planar和packed.planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V,这里所讲述的就是这中存储格式的:packed的YUV ...

  9. C语言:十进制进制转换为其他进制(思想:查表法)

    // //  main.c //  Hex conversion // //  Created by ma c on 15/7/22. //  Copyright (c) 2015年 bjsxt. A ...

随机推荐

  1. day-3

    /* 快noip了!!!感觉还有好多事要做 上午考试 原题没做 自己找了套题 挺水的 T1模拟(然而没认真读题 90) T2 dp+简单优化 数据有点问题 T3 暴力状丫 然而写丑了 60分的要两秒多 ...

  2. Wireshark - 过滤规则

    使用 Wireshark 的默认设置抓包时,会得到大量的冗余信息,以至于很难找到自己所需的封包.使用过滤器可以帮助我们在庞杂的结果中快速地找到我们所需的封包.过滤器分为两种:捕捉过滤器和显示过滤器. ...

  3. C#中out和ref使用

    1.out必须在方法中为其赋值,在调用的时候必须在变量的前面加上out关键字,侧重输出. 2.ref修饰方法的参数,在调用的时候必须在变量的前面加上ref关键字,可以修改其值也可以不修改,侧重修改. ...

  4. 20160501--struts2入门3

    一.自定义拦截器 要自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口: public class PermissionInterc ...

  5. 转载---SQL Server XML基础学习之<5>--XQuery(query)

    本章写一些SQL Server XML的一些XQuery基础语法,主要讲的query查询语法 T-SQL 支持用于查询 XML 数据类型的 XQuery 语言的子集. XQuery 基于现有的 XPa ...

  6. UIView的常见属性

    UIView的常见属性: @interface UIView : UIResponder<NSCoding, UIAppearance, UIAppearanceContainer, UIDyn ...

  7. C#获取时间戳的问题

    最近在做一个接口,需要用到时间戳,在请求接口时,返回超时,接口方的技术称是时间戳的不对(超出一定范围[比如1分钟]就返回超时)导致的. 首先,看代码: public static double Get ...

  8. 记一次ftp服务器错误 centOS 6.4 vsftpd 500 illegal port command

    这个错误是因为是主动模式的,应该改为被动模式 以下是操作过程: iptables中加 -A INPUT -p tcp -m state --state NEW -m tcp --dport 10221 ...

  9. P1396 营救

    P1396 营救 218 通过 571 提交 题目提供者yeszy 标签 二分 图论 并查集 福建省历届夏令营 难度 普及- 题目描述 "咚咚咚--""查水表!" ...

  10. Codevs 1225 八数码难题

    1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的 ...