最简单的CRC32源码-查表法
这个算法是在逐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源码-查表法的更多相关文章
- 最简单的CRC32源码---逐BIT法
CRC其实也就那么回事,却在网上被传得神乎其神.单纯从使用角度来说,只需要搞明白模二除法,再理解一些偷懒优化的技巧,就能写出自己的CRC校验程序. 下面的代码完全是模拟手算过程的,效率是最低的,发出来 ...
- 最简单的CRC32源码-逐BYTE法
从按BIT计算转到按BYTE计算,要利用异或的一个性质,具体见前面的文章<再探CRC >. 其实方法跟逐BIT法是一样的,我们只是利用异或的性质,把数据分成一BYTE一BYTE来计算,一B ...
- C#,Java,C -循环冗余检验:CRC-16-CCITT查表法
C#代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...
- 嵌入式C语言查表法的项目应用
嵌入式C实战项目开发技巧:如果对一个有规律的数组表进行位移操作 就像下面的这个表 之前写过上面这个标题的一篇文章,讲的是以位移的方式去遍历表中的数据,效率非常高,但是,如果要实现一个乱序的流水灯或者跑 ...
- 嵌入式C语言查表法
转自:https://blog.csdn.net/morixinguan/article/details/51799668 作者:Engineer-Bruce_Yang 就像下面的这个表 之前写 ...
- 经典算法,yuv与rgb互转,查表法,让你的软件飞起来
代码的运算速度取决于以下几个方面 1. 算法本身的复杂度,比如MPEG比JPEG复杂,JPEG比BMP图片的编码复杂. 2. CPU自身的速度和设计架构 3. CPU的总线带宽 4. 您自己代码的写法 ...
- 【C语言学习笔记】空间换时间,查表法的经典例子!知识就是这么学到的~
我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移植性那些角度. 在我们嵌入式中,我们需要根据实际资源的情况来设计我们的代码.比如当我们能用 ...
- YUV420查表法高效、无失真的转换为RGB32格式
YUV格式有两大类:planar和packed.planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V,这里所讲述的就是这中存储格式的:packed的YUV ...
- C语言:十进制进制转换为其他进制(思想:查表法)
// // main.c // Hex conversion // // Created by ma c on 15/7/22. // Copyright (c) 2015年 bjsxt. A ...
随机推荐
- HDU-1018(简单数学)
Big Number Problem Description In many applications very large integers numbers are required. Some o ...
- 【转】浅谈Java中的hashcode方法(这个demo可以多看看)
浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...
- C# ado.net 使用 row_number over() 简单的分页示例
/// <summary> /// 获取Paging列表 /// </summary> public List<HousesAgentEntity> GetPage ...
- HttpServlet was not found on the Java
今天新建jsp时出现了一个错误,如下图 分析:应该是没有找到相关jar包 解决方案: 如图: 这回就没错了
- JAVA深入研究——Method的Invoke方法
http://www.cnblogs.com/onlywujun/p/3519037.html 在写代码的时候,发现Method可以调用子类的对象,但子类即使是改写了的Method,方法名一样,去调用 ...
- SQLServer实现split分割字符串到列
网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题. 先贴上某大牛写的sp ...
- C#中运用事件实现异步调用
问题引出: winform程序中的耗时操作,一般不能在UI线程中执行,需要另开线程.往往我们需要在耗时操作结束后将结果显示在UI上. 以下是Mainform.cs中调用耗时操作的一段代码: Job j ...
- SSM配置
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- XSS漏洞(跨站脚本)
不要轻信用户提交上来的数据alert消息太难看,因此开发一个aspx页面用来统一展示消息ShowMessage.ashx //主页将判断重定向到另一个页面 if (TextBox1.Text != & ...
- 通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(一)
项目组用air来开发手游, 但有些在原生应用里很容易实现的功能没有办法在air中直接调用,比如说震动,服务等等.但Adobe 提供了一种方法让air间接调用本地代码(java,object-c...) ...