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

u32 CRC_Table[]; 

/*******************************CRC校验程序***********************************/
//作者 Skystalker
//输入32位
//多项式,省略最高位1 0x4C11DB7 CCITT-32:   0x04C11DB7  =  x32 + x26 +  x23 + x22 + x16 + x12 +
//                              x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
//数据不revert 结果不revert
//初值0x00000000或0xFFFFFFFF,其实所谓的初值就是原始数据要不要跟0xFFFFFFFF先异或先放到Reg中计算,用0xFFFFFFFF只是为了让别人不
//会一下就看出生成多项式是多少
//结果不异或
//验证网址:http://www.zorc.breitbandkatze.de/crc.html
//算法中数据向左移动,相对手工计算等效于生成多项式向右移动,所以不需要在后面加一大堆0
u32 CRC_Check_Software(u8 *ucpData,u8 Length)
{
    u32 Reg;//CRC寄存器,即传统除法中的余数
    u32 tempbyte=;
    u8 i;
    u8 count;
    u8 j=;
    u8 u32DataLen=((Length/)>)?((Length/)+):(Length/);
    u32 uipData[]={};
    //把byte组合成32位一组的数据放入uipData
    ;i<Length;i++)
    {
        uipData[i/]|=((u32)(*(ucpData+i)))<<(*(j-));
        j--;
        )
        {
            j=;
        }
    }
    //以下是算法开始
    //查表法
    ;count<u32DataLen;count++)
    {
        Reg=uipData[count];
        //Reg^=0xffffffff;//如果初值为0x00000000就把这行注释掉,否则不要注释
        ;i<;i++)
        {
            tempbyte=CRC_Table[(u8)(( Reg >>  ) & 0xff)];        //取一个字节,查表
            Reg=Reg<<;            //丢掉计算过的头一个BYTE
            Reg^=tempbyte;        //与前一个BYTE的计算结果异或
        }
    }

    //查表法
    return Reg;
}

/***********************************单字节32位CRC校验表生成函数*******************************/
//作者 Skystalker
//多项式,省略最高位1 0x4C11DB7 CCITT-32:   0x04C11DB7  =  x32 + x26 +  x23 + x22 + x16 + x12 +
//                              x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
//数据不revert 结果不revert
//结果不异或
//算法中数据向左移动,相对手工计算等效于生成多项式向右移动,所以不需要在后面加一大堆0
void CreateCRCTable(void)
{
    u16 Data,j;
    u32 tempbyte;
    u32 poly=0x4C11DB7; //生成多项式
    ;Data<;Data++)
    {
        tempbyte=((u32)Data)<<;
        ;j<;j++)
        {
            if(tempbyte&0x80000000)
            {
                tempbyte=tempbyte<<;    //要异或时Reg的最高位是1,CRC多项式最高位一直就是1,异或后必为0,所以一开始就偷懒把CRC多项式去掉最高位变成
                                        //0x4C11DB7 ,所以相应的这时候要把Reg左移一位,只要异或后边的32位
                tempbyte^=poly;
            }
            else
            {
                tempbyte=tempbyte<<;
            }
        }
        CRC_Table[Data]=tempbyte;
    }
}

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

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

#include <stdio.h>
#include <windows.h>

UINT CRC_Table[];

void CreateCRCTable(void)
{
    FILE * fp;
    unsigned __int16 Data,j;
    UINT tempbyte;
    UINT poly=0x4C11DB7;     //生成多项式
    if((fp=fopen("a.c","w"))==NULL)
    {
        printf("error\n");
    }
    fprintf(fp,"%s\n","UINT CRC_Table[256]=");
    fprintf(fp,"%c\n",'{');

    ;Data<;Data++)
    {
        tempbyte=((UINT)Data)<<;
        ;j<;j++)
        {
            if(tempbyte&0x80000000)
            {
                tempbyte=tempbyte<<;    //要异或时Reg的最高位是1,CRC多项式最高位一直就是1,异或后必为0,所以一开始就偷懒把CRC多项式去掉最高位变成
                                        //0x4C11DB7 ,所以相应的这时候要把Reg左移一位,只要异或后边的32位
                tempbyte^=poly;
            }
            else
            {
                tempbyte=tempbyte<<;
            }
        }
        CRC_Table[Data]=tempbyte;
        )
        fprintf(fp,"%s%x\n","0x",CRC_Table[Data]);
        else
        fprintf(fp,"%s%x%c","0x",CRC_Table[Data],',');

    }
    fprintf(fp,"%s\n","};");
}

int main()
{
    CreateCRCTable();
    return TRUE;
}

最简单的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. 手动修复OneDrive的DNS污染屏蔽的方法

    随着云计算的发展和微软云战略的持续推进,使用网盘进行文档存储.协同编辑与共享已成为文档操作的新流程.而Office.Office 365和OneDrive等微软产品是Windows用户的首选.但由于国 ...

  2. javax.servlet.ServletException: Servlet execution threw an exception 异常解决之一

    配置JDBC连接的JDBC.properties文件不存在(那天很奇怪配置文件不存在了,我也没有去移动那个文件.诡异呀)也会导致这个异常. 然后就报javax.servlet.ServletExcep ...

  3. AudioStreamer使用之快速点击下/上一首按钮,音频会重复的问题解决。

    针对此问题,我的做法是在AudioStreamer.h文件新加入一个属性 @property (nonatomic,strong) NSURL *musicUrl; 和一个单例方法: +(id)sha ...

  4. OC 消息传递机制

    消息传递(message passing)的概念是Smalltalk语言的核心原则之一,有时Smalltalk和Objective-C被称为面向消息的语言,通常“消息”一词的含义和“方法”是相同的. ...

  5. 是么是 API 和 SDK

    API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码 ...

  6. swift-07-使用for-in 遍历数组

    //for-in /* for 迭代变量 in集合变量 { 使用迭代变量便利所有数据 } */ //遍历数组 var arr = ["a" ,"b" ,&quo ...

  7. 基于注解整合struts2与spring的时候如果不引入struts2-spring-plugin包自动装配无效

    基于注解整合struts2与spring的时候如果不引入struts2-spring-plugin包,自动装配将无效,需要spring注入的对象使用时将抛出空指针异常(NullPointerExcep ...

  8. std::map的操作:插入、修改、删除和遍历

    using namespace std; std::map<int,int> m_map; 1.添加 for(int i=0;i<10;i++) { m_map.insert(mak ...

  9. MongoDB源码分析——mongod程序源码入口分析

    Edit 说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他 ...

  10. height为100%的问题

    问题描述 很多同学,对于设置div 的高度为100%时,有疑惑. 设置div 的高度为100%,意思是此 div 的高度 铺满父元素. 那么 怎么使 div 铺满浏览器屏幕? 代码 <!DOCT ...