最近在做软件升级,需要对升级文件进行crc校验,就学习了crc的实现原理

crc就是一个数值,该数值用于检验数据的正确性,crc校验的原理就是将需要作校验的数据与一个数据模2相除,得到的余数即为校验值。

模2相除就是在除的过程中用模2加,模2加实际上就是异或运算,就是不进行进位操作,即相同为假,不相同为真。

下面是几种CRC校验的生成多项式:

CRC8 = X8+X5+X4+1

CRC-CCITT = X16+X12+X5+1

CRC16=X16+X15+X2+1

CRC12=X12+X11+X3+X2+1

CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1

一个多项式就是一个比特流,也就是由0、1组合起来的一组数

我们需要获取的常数就是上面多项式所对应的反转多项式(反转多项式:在数据通讯时,信息字节先传送或接受低位字节,如重新排列则影响速度)。

下面使用查表法实现crc校验,具体步骤如下:

(1)将上次计算出的CRC校验码右移一个字节;
(2)将移出的这个字节与新的要校验的字节进行XOR 运算;
(3)用运算出的值在预先生成码表中进行索引,获取对应的值(称为余式);
(4)用获取的值与第(1)步右移后的值进行XOR 运算;
(5)如果要校验的数据已经处理完,则第(4)步的结果就是最终的CRC校验码。如果还有数据要进行处理,则再转到第(1)步运行。

本例使用crc32校验,使用上面crc32的生成多项式,值为0xEDB88320

首先写一个功能函数,实现生成一个crc表,然后写一个功能函数,用于计算crc值,最后再写一个函数用于比较crc值,下面是全部代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdint.h>uint32_t crc32_table[256];int make_crc32_table()
{uint32_t c;int i = 0;int bit = 0;for(i = 0; i < 256; i++){c  = (uint32_t)i;for(bit = 0; bit < 8; bit++){if(c&1){c = (c >> 1)^(0xEDB88320);}else{c =  c >> 1;}}crc32_table[i] = c;}}uint32_t make_crc(uint32_t crc, unsigned char *string, uint32_t size)
{while(size--)crc = (crc >> 8)^(crc32_table[(crc ^ *string++)&0xff]);return crc;
}void compare_crc(char *filename)
{FILE *sp = NULL;uint32_t srcCrc ;uint32_t calcuCrc = 0xffffffff;unsigned char buf[1024];uint32_t count;if(filename == NULL){printf("filename is null\n");exit(1);}sp = fopen(filename, "rb");if(sp == NULL){printf("open file fail\n");exit(1);}fread(&srcCrc, 1, 4, sp);printf("In %s: src crc is 0x%x\n", __FUNCTION__, srcCrc);  if(sp){while(!feof(sp)){memset(buf, 0, sizeof(buf));count = fread(buf, 1, sizeof(buf), sp);calcuCrc = make_crc(calcuCrc, buf, count);}}printf("In %s: calcuCrc is 0x%x\n", __FUNCTION__, calcuCrc);fclose(sp);if(srcCrc == calcuCrc){printf("In %s: the calculate crc equal the src crc in file \n", __FUNCTION__);}else{printf("In %s: the calculate crc not equal the src crc in file \n", __FUNCTION__);}}int main()
{int i;FILE *sp = NULL;FILE *dp = NULL;uint32_t count;uint32_t crc = 0xFFFFFFFF;unsigned char buf[1024];make_crc32_table();sp = fopen("/home/user/work_soft/crc_check/bak/test.txt", "rb");if(sp == NULL){printf("open file error\n");return -1;}dp = fopen("/home/user/work_soft/crc_check/bak/testcrc.txt", "wb");if(dp == NULL){printf("open file error\n");return -1;}if(sp){while(!feof(sp)){memset(buf, 0, sizeof(buf));count = fread(buf, 1, sizeof(buf), sp);crc = make_crc(crc, buf, count);        }}printf("In main: calculate crc is 0x%x\n", crc);if(dp){fwrite(&crc, 1, 4, dp);//write the crc into the file testcrc.txtfseek(sp, 0, SEEK_SET);while(!feof(sp)){memset(buf, 0, sizeof(buf));count = fread(buf, 1, sizeof(buf), sp);fwrite(buf, 1, count, dp);}fclose(sp);fclose(dp);}/*compare crc*/compare_crc("/home/user/work_soft/crc_check/bak/testcrc.txt");return 0;}

上面代码是根据查表法实现的,首先生成crc表,make_crc32_table就是根据crc校验的原理实现的,对0-255进行模2除法生成crc表;

函数make_crc是根据查表法的步骤实现的;而函数compare_crc则用来打开一个在头部嵌入crc值的文件,首先将文件头部的crc值取出(若用于功能实现,可设计一个数据结构用于存放crc等相关值,并存放在文件的头部),然后再读取文件的余下内容进行

crc计算,将计算出的crc值与从文件中读出的crc值进行比较,若相等则说明文件内容没有出错。下面是运行结果:

如果要将crc嵌入到文件头部,比如将计算得出的crc嵌入到升级文件的头部,由于我们生成的crc值的存储方式可能会因为不同的主机而不同(大端或小端)

所以在将crc值嵌入到升级文件的头部时,最好再加一个字节用于说明crc值得存储方式是大端还是小端模式,这样接收方就可以选择同一个存储方式,来确定读取的crc值是正确的

crc32校验的c语言实现相关推荐

  1. 【转载】CRC32校验算法C语言版(查表法)

    先放原文链接:CRC32校验算法C语言版(查表法) 这几天搞串口通信,用到CRC32,把以前用到的东西整理一下,方便以后使用. STM32F103 芯片自带的CRC32硬件算法,匹配上位机CRC32算 ...

  2. C语言对文件进行crc32校验

    C语言对文件进行crc32校验 参考代码(包含测试代码)如下: #include <stdio.h> #include <stdlib.h> #include <stri ...

  3. C语言实现CRC16和CRC32校验

    一.CRC32校验代码 static const unsigned int crc32tab[] = {  0x00000000L, 0x77073096L, 0xee0e612cL, 0x99095 ...

  4. bcc校验码计算_CRC校验你会吗?计算、校验、C语言实现,三步教你轻松搞定

    目录 前言 CRC算法简介 CRC计算 CRC校验 CRC计算的C语言实现 CRC计算工具 总结 前言 最近的工作中,要实现对通信数据的CRC计算,所以花了两天的时间好好研究了一下,周末有时间整理了一 ...

  5. 异或校验算法 c语言程序,C# 异或校验算法

    C# 的异或校验算法 直接上代码 public partial class FormCRC : Form { public FormCRC() { InitializeComponent(); } p ...

  6. CRC校验及C语言实现

    摘自:CRC校验原理及其C语言实现 地址:https://blog.csdn.net/whik1194/article/details/108837493?spm=1001.2014.3001.550 ...

  7. crc16,crc32校验

    crc16,crc32校验 -supermgr crc16,crc32校验是计算机中经常用到的东西, 本文介绍的程序,使用查表法来进行crc16,crc32的校验. //file: sp_crc.h ...

  8. C#:实现CRC32校验算法(附完整源码)

    C#:实现CRC32校验算法 /// <summary>/// 计算给定长度数据的32位CRC/// </summary>/// <param name="da ...

  9. Linux 大文件crc计算,Windows和Linux下使用MD5、SHA1、CRC32校验备份文件的完整性

    因为经常会用到备份加密压缩过的数据到不同的服务器,然而这些服务器是否可靠,服务器的提供者是否值得信任,为了保证文件的完整性不被篡改,也为了多个地方存储的同一个大文件的备份自己能够快速的识别出来是否是同 ...

最新文章

  1. springboot初学
  2. Android面试题(五) --重要
  3. python3 匹配空格 正则_玩转正则表达式
  4. C语言循环结构素数判断,C语言实验之判断素数(循环结构java)方法讲解
  5. 第十七期:详解大数据处理中的Lambda架构和Kappa架构
  6. 心血来潮,小试c++11
  7. js 二维数组_JS数独验证--难度☆☆☆☆☆
  8. java qq 邮箱发送错误以及端口号
  9. java去掉边框_java swing怎么去掉边框
  10. 如何将一个服务器加入域控中,Windows Server如何创建域并加入域
  11. pycharm “collecting data“
  12. MAC 扩展屏,颜色描述文件
  13. 【C++】C++11 新特性
  14. 国产CAD制图软件中怎么设置两点标注?
  15. Python自动生成代码 - 通过tkinter图形化操作生成代码框架
  16. Pytorch squeeze()的简单用法
  17. 李思廉的“穷人逻辑”:给咸鱼卖个好价
  18. Markdown For Typora
  19. 浅谈UML---类图
  20. 家庭卡拉OK的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告

热门文章

  1. GLAD应用:体全息光栅模拟
  2. 视频转图片序列 java_OpenCV 视频与图片序列相互转换
  3. 蹭WiFi掉黑客陷进怎么破
  4. 10400(核显)+b460m迫击炮Wi-Fi版+bigsur11.15.1+基本完美
  5. Linux ora-12514多实例,ORA-12514问题解决
  6. Spring Aspect @PointCut(execution表达式)
  7. 台式机计算机硬件检测,台式电脑常见硬件故障检查和排除怎么做?
  8. 计算机软硬件故障排除知识,计算机软硬件基础知识及常见故障排除方法(精选).doc...
  9. python演化博弈仿真_演化博弈应用:例子与思路
  10. 微信跳一跳脚本制作思路