当前位置: 首页 > news >正文

CRC校验 (查表方式) 通用源码(兼容CRC4/5/6/7/8/16/32/自定义),包含 CRC表数据的计算代码

下面包含了CRC校验 通用代码CRC表数据的计算代码。实际应用可以根据CRC类型裁剪代码,可以直接把打印输出的表直接存放在ROM区,减少代码量。

#include <stdio.h> #include <string.h> /**Private typedef*************************************************************/ /* USER CODE BEGIN PT */ typedef enum { CRC4_ITU = 0, CRC5_EPC, CRC5_ITU, CRC5_USB, CRC6_ITU, CRC7_MMC, CRC8, CRC8_ITU, CRC8_ROHC, CRC8_MAXIM, CRC16_IBM, CRC16_MAXIM, CRC16_USB, CRC16_MODBUS, CRC16_CCITT, CRC16_CCITT_FALSE, CRC16_X25, CRC16_XMODEM, CRC16_DNP, CRC32, CRC32_MPEG2, CRC_NUM }CrcTypeE; typedef enum { E_FALSE = 0, //假(错误) E_TRUE = !E_FALSE //真(正确) }BoolTypeE; typedef struct { const char *Name; unsigned char Width; //宽度,即CRC比特数。 unsigned int Poly; //生成多项式的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。 unsigned int CrcInit; //初始值,这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。 unsigned int XorOut; //计算结果与此参数异或后得到最终的CRC值。 BoolTypeE RefIn; //待测数据的每个字节是否按位反转,E_TRUE或E_FALSE。 BoolTypeE RefOut; //在计算后之后,异或输出之前,整个数据是否按位反转,E_TRUE或E_FALSE。 }CrcInfoTypeS; /* USER CODE END PT */ /**Private variables***********************************************************/ /* USER CODE BEGIN PV */ const static CrcInfoTypeS s_crcInfoTab[CRC_NUM] = { //CRC算法名称 宽度 多项式 初始值 结果异或值 输入反转 输出反转 适用场景说明 {"CRC4_ITU", 4, 0x03, 0x00, 0x00, E_TRUE, E_TRUE}, // 电信4bit短报文 {"CRC5_EPC", 5, 0x09, 0x09, 0x00, E_FALSE, E_FALSE}, // RFID EPC电子标签 {"CRC5_ITU", 5, 0x15, 0x00, 0x00, E_TRUE, E_TRUE}, // ITU-T 5bit通信校验 {"CRC5_USB", 5, 0x05, 0x1F, 0x1F, E_TRUE, E_TRUE}, // USB低速5bit帧校验 {"CRC6_ITU", 6, 0x03, 0x00, 0x00, E_TRUE, E_TRUE}, // 6bit低速通信短帧 {"CRC7_MMC", 7, 0x09, 0x00, 0x00, E_FALSE, E_FALSE}, // SD/MMC存储卡命令校验 {"CRC8", 8, 0x07, 0x00, 0x00, E_FALSE, E_FALSE}, // 通用简易8位校验 {"CRC8_ITU", 8, 0x07, 0x00, 0x55, E_FALSE, E_FALSE}, // ITU-T标准8位CRC {"CRC8_ROHC", 8, 0x07, 0xFF, 0x00, E_TRUE, E_TRUE}, // ROHC网络压缩协议 {"CRC8_MAXIM", 8, 0x31, 0x00, 0x00, E_TRUE, E_TRUE}, // DS18B20 1-Wire总线 {"CRC16_IBM", 16, 0x8005, 0x0000, 0x0000, E_TRUE, E_TRUE}, // CRC16-ARC,通用简易16位校验 {"CRC16_MAXIM", 16, 0x8005, 0x0000, 0xFFFF, E_TRUE, E_TRUE}, // Maxim配套CRC16校验 {"CRC16_USB", 16, 0x8005, 0xFFFF, 0xFFFF, E_TRUE, E_TRUE}, // USB总线16位校验 {"CRC16_MODBUS", 16, 0x8005, 0xFFFF, 0x0000, E_TRUE, E_TRUE}, // Modbus-RTU 485工控总线(最常用16位CRC) {"CRC16_CCITT", 16, 0x1021, 0x0000, 0x0000, E_TRUE, E_TRUE}, // CCITT标准,蓝牙基带 {"CRC16_CCITT_FALSE", 16, 0x1021, 0xFFFF, 0x0000, E_FALSE, E_FALSE}, // EtherCAT FoE/X.25 串口文件传输 {"CRC16_X25", 16, 0x1021, 0xFFFF, 0xFFFF, E_TRUE, E_TRUE}, // X.25、PPP拨号物联网模组 {"CRC16_XMODEM", 16, 0x1021, 0x0000, 0x0000, E_FALSE, E_FALSE}, // Xmodem/Ymodem串口文件上传 {"CRC16_DNP", 16, 0x3D65, 0x0000, 0xFFFF, E_TRUE, E_TRUE}, // DNP3电力工控通信协议 {"CRC32", 32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, E_TRUE, E_TRUE}, // CRC32 IEEE802.3 OTA固件/以太网FCS/ZIP文件校验 {"CRC32_MPEG2", 32, 0x04C11DB7, 0xFFFFFFFF, 0x00000000, E_FALSE, E_FALSE}, // MPEG2视频码流校验,不可用于固件升级 }; static unsigned int s_crcTab[256]; /* USER CODE END PV */ /** ******************************************************************************* * @brief 位反转 函数 * @param [in] inVal - 反转前数据 * @param [in] bits - 反转位数 * @return 反转后数据 * @note 就是将高位与低位数据顺序反过来。 ******************************************************************************* */ unsigned int BitsReverse(unsigned int inVal, unsigned char bits) { unsigned int outVal = 0; unsigned char i; for(i=0; i<bits; i++) { if(inVal & (1 << i)) outVal |= 1 << (bits - 1 - i); } return outVal; } /** ******************************************************************************* * @brief 获取 CRC(循环冗余校验) 函数 * @param [in] type - CRC 类型 * @param [in] *buf - 数据块指针 * @param [in] bufLen - 数据长度 * @return 校验码 * @note ******************************************************************************* */ unsigned int GetCRC(unsigned char type, unsigned char *buf, unsigned int bufLen) { unsigned char width = s_crcInfoTab[type].Width; //宽度,即CRC比特数。 unsigned int crc = s_crcInfoTab[type].CrcInit; //初始值,这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。 unsigned int xorout = s_crcInfoTab[type].XorOut; //计算结果与此参数异或后得到最终的CRC值。 unsigned char refin = s_crcInfoTab[type].RefIn; //待测数据的每个字节是否按位反转,E_TRUE或E_FALSE。 unsigned char refout = s_crcInfoTab[type].RefOut; //在计算后之后,异或输出之前,整个数据是否按位反转,E_TRUE或E_FALSE。 unsigned char high; if(refin) //逆序 LSB 输入 { crc = BitsReverse(crc, width); //init 先逆序; if(width > 8) //为了减少移位等操作,width大于8和小于8的分开处理 { while(bufLen--) { crc = (crc >> 8) ^ s_crcTab[(crc & 0xFF) ^ *buf++]; } } else { while(bufLen--) { crc = s_crcTab[crc ^ *buf++]; } } } else //正序 MSB 输入 { if(width > 8) //为了减少移位等操作,width大于8和小于8的分开处理 { while (bufLen--) { high = crc >> (width - 8); crc = (crc << 8) ^ s_crcTab[high ^ *buf++]; } } else { crc = crc << (8 - width); while (bufLen--) { crc = s_crcTab[crc ^ *buf++]; } crc >>= 8 - width; //位数小于8时,crc在高width位,要右移到原位 } } if(refout != refin) //逆序输出 { crc = BitsReverse(crc, width); } crc ^= xorout; //异或输出 return crc & ((2 << (width - 1)) - 1); } /** ******************************************************************************* * @brief 打印CRC表 函数 * @param [in] type - CRC算法类型 * @return None * @note ******************************************************************************* */ void PrintfCrcTab(unsigned char type) { unsigned int i; printf("s_crcTab = \n{//%s", s_crcInfoTab[type].Name); for(i=0; i<256; i++) { if(i%16==0) printf("\n "); if(s_crcInfoTab[type].Width < 9) printf("0x%02X, ", s_crcTab[i]); else if(s_crcInfoTab[type].Width < 17) printf("0x%04X, ", s_crcTab[i]); else printf("0x%08X, ", s_crcTab[i]); } printf("\n};\n\n"); } /** ******************************************************************************* * @brief CRC表创建 函数 * @param [in] type - CRC算法类型 * @return None * @note ******************************************************************************* */ void CrcTableCalculate(unsigned char type) { unsigned char width = s_crcInfoTab[type].Width; //宽度,即CRC比特数。 unsigned int poly = s_crcInfoTab[type].Poly; //生成多项式的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。 unsigned char refIn = s_crcInfoTab[type].RefIn; //待测数据的每个字节是否按位反转,E_TRUE或E_FALSE。 unsigned int validBits = (2 << (width - 1)) - 1; unsigned int value; unsigned int bit; unsigned int i; unsigned char j; if(refIn) //逆序LSB输入 { poly = BitsReverse(poly, width); //poly先逆序, s_crcTab 的 CrcInit = 0; for(i=0; i<256; i++) { value = i; for(j=0; j<8; j++) { if(value & 1) { value = (value >> 1) ^ poly; } else { value = (value >> 1); } } s_crcTab[i] = value & validBits; } } else //正序MSB输入 { poly = (width < 8) ? (poly << (8 - width)) : poly; //如果位数小于8,poly要左移到最高位 bit = (width > 8) ? (1 << (width - 1)) : 0x80; for(i=0; i<256; i++) { value = (width > 8) ? (i << (width - 8)) : i; for(j=0; j<8; j++) { if(value & bit) { value = (value << 1) ^ poly; } else { value = (value << 1); } } s_crcTab[i] = value & ((width < 8) ? 0xFF : validBits); } } PrintfCrcTab(type); } /** ******************************************************************************* * @brief 主函数 * @param [in] None * @return None * @note 验证校验函数 ******************************************************************************* */ void main() { char *str = "Hello World!"; unsigned int i; for(i=0; i<CRC_NUM; i++) { CrcTableCalculate(i); //CRC表创建 printf("%s (\"%s\") = 0x%0X\n\n", s_crcInfoTab[i].Name, str, GetCRC(i, (unsigned char*)str, strlen(str))); } while(1); }

运行结果:(篇幅大,截取了部分输出)

http://www.jsqmd.com/news/1034869/

相关文章:

  • 庆阳市2026年最新黄金回收铂金回收白银回收彩金回收五家靠谱门店及联系方式地址电话推荐TOP5排行榜 - 亦辰小黄鸭
  • 医疗AI落地实战:重构临床工作流的七道关卡
  • 丽江市2026年最新黄金回收铂金回收白银回收彩金回收五家靠谱门店及联系方式地址电话推荐TOP5排行榜 - 亦辰小黄鸭
  • 2026年阜阳市大众首选贵金属靠谱回收商户名录TOP5 黄金回收白银回收铂金回收彩金回收线下回收门店信息一览+联系方式推荐 - 前途无量YY
  • 茂名电白区上门疏通管道 2026 真实评测最新综合排行榜 - 居顺联家政疏通
  • 多维聚合数据变形术:构建可导航的维度空间
  • 丽水市2026年最新黄金回收铂金回收白银回收彩金回收五家靠谱门店及联系方式地址电话推荐TOP5排行榜 - 亦辰小黄鸭
  • 微信投票教程|众星评选免费小程序发起图片视频投票 - 微信投票小程序
  • 2026年赣州市大众首选贵金属靠谱回收商户名录TOP5 黄金回收白银回收铂金回收彩金回收线下回收门店信息一览+联系方式推荐 - 前途无量YY
  • 书法培训机构学员作品投票工具推荐|免费好用防刷票小程序 - 微信投票小程序
  • 混元Image3.0:分层VAE架构下的可控文生图新范式
  • Hugging Face Datasets工程实战:Streaming、Map、Concatenate与Metrics避坑指南
  • JSON格式化使用教程:从入门到精通
  • 2026海西市民高频选择的 5 家家电回收门店实地测评整理冰箱洗衣机空调电视回收+工商备案+联系方式推荐 - 诚金汇钻回收公司
  • AI 编译优化实战:从计算图到算子融合的推理加速路径
  • 深度解析:ReActor AI换脸插件架构设计与高性能部署指南
  • 2026邯郸市民高频选择的 5 家家电回收门店实地测评整理冰箱洗衣机空调电视回收+工商备案+联系方式推荐 - 诚金汇钻回收公司
  • 机器学习可解释性:模型落地前的最后一道安检
  • Windows 11右键菜单自定义神器:5分钟打造您的专属效率工具箱
  • 2026年固原市大众首选贵金属靠谱回收商户名录TOP5 黄金回收白银回收铂金回收彩金回收线下回收门店信息一览+联系方式推荐 - 前途无量YY
  • 2026急售莫奈任人宰割,身在杭州西湖区差价能差出上万 - 逸程
  • 长沙婚嫁三金旧黄金回收攻略|全城正规门店 S/A 级实测清单 - 奢侈品回收测评
  • 网络协议解析:Soft Parser运算符与帧属性标志实战详解
  • 连云港市2026年最新黄金回收铂金回收白银回收彩金回收五家靠谱门店及联系方式地址电话推荐TOP5排行榜 - 亦辰小黄鸭
  • 2026年滨州市大众首选贵金属靠谱回收商户名录TOP5 黄金回收白银回收铂金回收彩金回收线下回收门店信息一览+联系方式推荐 - 前途无量YY
  • 辽源市2026年最新黄金回收铂金回收白银回收彩金回收五家靠谱门店及联系方式地址电话推荐TOP5排行榜 - 亦辰小黄鸭
  • 2026阿坝市民高频选择的 5 家家电回收门店实地测评整理冰箱洗衣机空调电视回收+工商备案+联系方式推荐 - 诚金汇钻回收公司
  • 2026白山市民高频选择的 5 家黄金白银铂金回收店实地测评整理+中检官方认证+联系方式推荐 - 中安检金银铂钻回收
  • 2026石家庄回收古驰包包,正规无套路一线奢包回收实测榜单 - 名奢变现站
  • 2026年亳州市大众首选贵金属靠谱回收商户名录TOP5 黄金回收白银回收铂金回收彩金回收线下回收门店信息一览+联系方式推荐 - 前途无量YY