最近用到CRC校验算法,就找了些资料,学习了一下,网上关于CRC32的资料也多,但感觉不是很完整,或者太高深。

CRC算法查表法很常见,但表是怎么来的,有些资料说得不很清楚。

我来说一下我的看法:

1.CRC校验变化太多,有CRC4/5/6/7/8/16/32,每一种的多项式也有很多种变化,并不是一成不变的;

2.输入输出方式也有区别,有一些初始值是0,有一些初始值是0xFFFFFFFF,有一些直接返回,有一些异或返回。

因此,CRC校验很难用一个代码兼容全部,只能根据项目需要修改相关参数了。

计算方法:

1.先要知道多项式是什么样子,以这个IEEE802.3标准CRC32多项式为例:x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x+ 1

2.转换成一个值(这个值的命名我不知道啊)

x32 则对应32bit = 1, x26 则对应26bit=1,得出一个值:(1<<32)|(1<<26)|(1<<23)|(1<<22)|…|(1<<1)|(1)=0x104C11DB7,对于CRC32取低32位,则=0x4C11DB7
3.用这个值通过一定方法生成长度为256的码表,对于CRC32表内每个元素都为32bit.

4.用一定的方法查表得出CRC32值。

好了,可以贴代码了:

[cpp] view plaincopyprint?
/*

  • CRC校验算法,查表法
    */
    #include “crc.h”

static unsigned long table[256];

//位逆转
static unsigned long bitrev(unsigned long input, int bw)
{
int i;
unsigned long var;
var = 0;
for(i=0;i<bw;i++)
{
if(input & 0x01)
{
var |= 1<<(bw-1-i);
}
input>>=1;
}
return var;
}

//码表生成
//如:X32+X26+…X1+1,poly=(1<<26)|…|(1<<1)|(1<<0)
void crc32_init(unsigned long poly)
{
int i;
int j;
unsigned long c;

poly=bitrev(poly,32);
for(i=0; i<256; i++)
{  c = i;  for (j=0; j<8; j++)  {  if(c&1)  {  c=poly^(c>>1);  }  else  {  c=c>>1;  }  }  table[i] = c;
}

}

unsigned long crc32(unsigned long crc, void* input, int len)
{
int i;
unsigned char index;
unsigned char* pch;
pch = (unsigned char*)input;
for(i=0;i<len;i++)
{
index = (unsigned char)(crc^*pch);
crc = (crc>>8)^table[index];
pch++;
}
return crc;
}

测试用例:

[cpp] view plaincopyprint?
void main(void)
{
unsigned long crc;
crc32_init(0x4C11DB7,table);

crc = 0xFFFFFFFF;
crc=crc32(crc,"1234567890",10);
crc ^= 0xFFFFFFFF;
printf("CRC32=%08X\n",crc);
system("pause");

}

计算结果:

CRC32=0x261DAEE5

crc32算法简单理解相关推荐

  1. 模拟退火算法简单理解

    模拟退火算法 算法流程图 1. 引言 模拟退火算法(Simulate Anneal,SA)是一种通用概率演算法,用来 在一个大的搜寻空间内找寻命题的最优解 .模拟退火是由S.Kirkpatrick, ...

  2. Blossom算法,开花算法简单理解

    有条件的建议去油管上看,讲的很清楚https://www.youtube.com/watch?v=3roPs1Bvg1Q 引例:如果你是夏令营负责人,你的任务是将一群人分为两组.为了公平起见,每个人在 ...

  3. 蒙特卡洛算法简单理解与demo

    所谓蒙特卡洛算法,实际上就是用频率估计概率. 首先我们知道一个边长为2的正方形面积是2*2=4,他的内接圆的面积是π*1,那么我们在这样一个正方形内随机生成10000个点,落在圆里的点的个数/1000 ...

  4. DFA算法简单理解实现

    背景:因为最近项目要使用到敏感词过滤服务,在网上了解到dfa实现这个功能性能还不错,特此学习了一下 1. 什么是DFA算法 引用 简书作者:浪人与酒丶的解释 原文链接:https://www.jian ...

  5. 基于错误扩散的Floyd-Steinbery抖动算法简单理解

    1. 图像处理中的dithering技术     它是一种欺骗你眼睛,使用有限的色彩让你看到比实际图象更多色彩的显示方式.通过在相邻像素间随机的加入不同的颜色来修饰图象,通常这种方式被用于颜色较少的情 ...

  6. CPD配准算法及代码的简单理解(Coherent Point Drift)

    我的毕业设计用到了CPD算法,以及CPD代码工具包,当时刚开始接触CPD时在网上没找到几篇教程或是经验总结的东西.现在毕设做完了,就结合我的理解写一篇文章.可能写的会有点乱,因为我也是一时兴起想要做一 ...

  7. 人工智能:深度学习算法及应用——简单理解CNN卷积神经网络并python实现(带源码)

    深度学习算法及应用 一. 实验目的 二. 实验要求 三. 实验的硬件.软件平台 四. 实验原理 1.1. 深度学习概述 1.2. 深度学习的常见结构 1.3. 卷积神经网络(CNN) **卷积** * ...

  8. 协同过滤算法的简单理解《推荐系统实践》

    协同过滤算法的简单理解 本文主要是讲解一下<推荐系统实践>中UserCF和ItemCF这两种基于领域的推荐算法,写出自己的理解. UserCF(基于用户的协同过滤算法) 这种推荐算法的出发 ...

  9. 直观地简单理解Tarjan算法(寻找有向图中的强连通图)

    简单理解Tarjan算法   按照百度百科的播报应该是读成['ta:rdʒən]?看过了几篇网络上的解释虽然都讲得比较具体但刚开始都难以理解,所以打算写一个更直观的理解方式.   Tarjan算法是求 ...

最新文章

  1. 图像处理与计算机视觉:基础,经典以及最近发展(3)计算机视觉中的信号处理与模式识别
  2. 直方图和直条图_绘图专题 | 条形图/直方图傻傻分不清楚
  3. 简述Intel的MESI缓存一致性协议
  4. 非root用户组启动sftp_如何在 Debian 10 中配置 Chroot 环境的 SFTP 服务 | Linux 中国
  5. [转]简析 IOS 程序图标的设计
  6. python线程池回调函数_python回调函数中使用多线程的方法
  7. 每日算法系列【LeetCode 153】寻找旋转排序数组中的最小值
  8. 基于51单片机的无线测温系统
  9. 从零开始学视觉里程计——一个初学者教程
  10. 涂鸦智能进击南美取暖器市场
  11. 让逆向工程师们头疼的代码混淆,就像永远也走不出的“浪浪山”
  12. MMI of UIQ
  13. Ubuntu下怎么退出vim编辑器
  14. linux LTP移植Android,LTP(Linux Test Project) for Android的编译
  15. 证明spring中property name=这个双引号的内容只与setter方法有关,与一个类定义的字段和getter方法无关...
  16. failed to connect to /172.20.100.117 (port 18899): isConnected failed: ECONNREFUSED (Connection refu
  17. 【容易打工网】大学生职场励志箴言励志语录
  18. 5款非常看好的电脑软件
  19. python画对比双色柱状图_如何在Python中绘制一列被另一列着色的柱状图?
  20. 【stm32】利用单片机实现小车直线和圆弧的识别

热门文章

  1. 软件测试物理机环境基础
  2. 面向对象三大特性之多态
  3. 通过设置路由器屏避小米电视盒子广告
  4. 细讲MyCat分库分表策略
  5. python 从excel中抓取数据_python接口自动化(三)——从excel中获取数据
  6. 科研作图及科研汇报PPT规范
  7. Linux JDK 卸载安装
  8. 高等数学课程学习网站设计应用
  9. React Native 学习笔记六(关于宽高的设置)
  10. mysql面试-分库分表