计算原理

函数接口

只需要知道所需CRC的模型,调用相应接口即可得到结果,文末附上常用CRC模型

/*** @brief 计算CRC通用算法* @param data 数据地址* @param lenth 数据长度* @param POLY 生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7* @param INIT 这是算法开始时寄存器(crc)的初始化预置值,十六进制表示* @param XOROUT 计算结果与此参数异或后得到最终的CRC值* @param REFIN 待测数据的每个字节是否按位反转,True或False* @param REFOUT 在计算后之后,异或输出之前,整个数据是否按位反转,True或False*/
uint8_t crc8_universal(uint8_t *data, uint32_t lenth, uint8_t POLY, uint8_t INIT, \uint8_t XOROUT, bool REFIN, bool REFOUT);uint16_t crc16_universal(uint8_t *data, uint32_t lenth, uint16_t POLY, uint16_t INIT, \uint16_t XOROUT, bool REFIN, bool REFOUT);uint32_t crc32_universal(uint8_t *data, uint32_t lenth, uint32_t POLY, uint32_t INIT, \uint32_t XOROUT, bool REFIN, bool REFOUT);

接口使用示例

计算CRC16-MODBUS的模型如下

CRC算法名称 多项式公式 宽度 多项式 初始值 结果异或值 输入反转 输出反转
CRC-16/MODBUS x16 + x15 + x2 + 1 16 8005 FFFF 0000 true true

接口使用方法如下

#include <stdio.h>
#include "crc_universal.h"uint16_t crc16_modbus(uint8_t *data, uint32_t lenth)
{return crc16_universal(data, lenth, 0x8005, 0xFFFF, 0x0000, true, true);
}int main(int argc, char const *argv[])
{uint8_t data[] = {0x56, 0x76, 0x88};uint16_t crc16;crc16 = crc16_modbus(data, 3);printf("crc = %04X\r\n", crc16);return 0;
}// 输出crc = D6B7

与网上提供的工具计算结果相同

源码

crc_universal.h

#ifndef __CRC_UNIVERSAL__
#define __CRC_UNIVERSAL__#include <stdint.h>
#include <stdbool.h>/*** @brief 计算CRC通用算法* @param data 数据地址* @param lenth 数据长度* @param POLY 生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7* @param INIT 这是算法开始时寄存器(crc)的初始化预置值,十六进制表示* @param XOROUT 计算结果与此参数异或后得到最终的CRC值* @param REFIN 待测数据的每个字节是否按位反转,True或False* @param REFOUT 在计算后之后,异或输出之前,整个数据是否按位反转,True或False*/
uint8_t crc8_universal(uint8_t *data, uint32_t lenth, uint8_t POLY, uint8_t INIT, \uint8_t XOROUT, bool REFIN, bool REFOUT);uint16_t crc16_universal(uint8_t *data, uint32_t lenth, uint16_t POLY, uint16_t INIT, \uint16_t XOROUT, bool REFIN, bool REFOUT);uint32_t crc32_universal(uint8_t *data, uint32_t lenth, uint32_t POLY, uint32_t INIT, \uint32_t XOROUT, bool REFIN, bool REFOUT);#endif

crc_universal.c

#include "crc_universal.h"/*** @brief 字节按位逆序  1100 0101 -> 1010 0011*/
static uint8_t bit8_reverse(uint8_t x)
{x = ((x >> 1) & 0x55) | ((x & 0x55) << 1); x = ((x >> 2) & 0x33) | ((x & 0x33) << 2);return ( x >> 4) | (x << 4);
}static uint16_t bit16_reverse(uint16_t x)
{x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1); x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2);x = ((x >> 4) & 0x0f0f) | ((x & 0x0f0f) << 4); return((x >> 8) | (x << 8));
}static uint32_t bit32_reverse(uint32_t x)
{x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));return((x >> 16) | (x << 16));
}uint8_t crc8_universal(uint8_t *data, uint32_t lenth, uint8_t POLY, uint8_t INIT, \uint8_t XOROUT, bool REFIN, bool REFOUT)
{uint8_t i, new_data;uint8_t crc;crc = INIT;for (; lenth> 0; lenth--){new_data = REFIN? bit8_reverse(*(data++)) : (*(data++));crc = crc ^ (new_data);for (i = 0; i < 8; i++)            {if (crc & 0x80)           crc = (crc << 1) ^ POLY;   else                          crc <<= 1;                 }}crc = REFOUT? bit8_reverse(crc) : crc;crc ^= XOROUT;return(crc);
}uint16_t crc16_universal(uint8_t *data, uint32_t lenth, uint16_t POLY, uint16_t INIT, \uint16_t XOROUT, bool REFIN, bool REFOUT)
{uint8_t i, new_data;uint16_t crc;crc = INIT;for (; lenth> 0; lenth--){new_data = REFIN? bit8_reverse(*(data++)) : (*(data++));crc = crc ^ (new_data << 8);for (i = 0; i < 8; i++)            {if (crc & 0x8000)           crc = (crc << 1) ^ POLY;   else                          crc <<= 1;                 }}crc = REFOUT? bit16_reverse(crc) : crc;crc ^= XOROUT;return(crc);
}uint32_t crc32_universal(uint8_t *data, uint32_t lenth, uint32_t POLY, uint32_t INIT, \uint32_t XOROUT, bool REFIN, bool REFOUT)
{uint8_t i, new_data;uint32_t crc;crc = INIT;for (; lenth> 0; lenth--){new_data = REFIN? bit8_reverse(*(data++)) : (*(data++));crc = crc ^ (new_data << 24);for (i = 0; i < 8; i++)            {if (crc & 0x80000000)           crc = (crc << 1) ^ POLY;   else                          crc <<= 1;                 }}crc = REFOUT? bit32_reverse(crc) : crc;crc ^= XOROUT;return(crc);
}

常用CRC模型

CRC算法名称 多项式公式 宽度 多项式 初始值 结果异或值 输入反转 输出反转
CRC-4/ITU x4 + x + 1 4 03 00 00 true true
CRC-5/EPC x5 + x3 + 1 5 09 09 00 false false
CRC-5/ITU x5 + x4 + x2 + 1 5 15 00 00 true true
CRC-5/USB x5 + x2 + 1 5 05 1F 1F true true
CRC-6/ITU x6 + x + 1 6 03 00 00 true true
CRC-7/MMC x7 + x3 + 1 7 09 00 00 false false
CRC-8 x8 + x2 + x + 1 8 07 00 00 false false
CRC-8/ITU x8 + x2 + x + 1 8 07 00 55 false false
CRC-8/ROHC x8 + x2 + x + 1 8 07 FF 00 true true
CRC-8/MAXIM x8 + x5 + x4 + 1 8 31 00 00 true true
CRC-16/IBM x16 + x15 + x2 + 1 16 8005 0000 0000 true true
CRC-16/MAXIM x16 + x15 + x2 + 1 16 8005 0000 FFFF true true
CRC-16/USB x16 + x15 + x2 + 1 16 8005 FFFF FFFF true true
CRC-16/MODBUS x16 + x15 + x2 + 1 16 8005 FFFF 0000 true true
CRC-16/CCITT x16 + x12 + x5 + 1 16 1021 0000 0000 true true
CRC-16/CCITT-FALSE x16 + x12 + x5 + 1 16 1021 FFFF 0000 false false
CRC-16/X25 x16 + x12 + x5 + 1 16 1021 FFFF FFFF true true
CRC-16/XMODEM x16 + x12 + x5 + 1 16 1021 0000 0000 false false
CRC-16/DNP x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1 16 3D65 0000 FFFF true true
CRC-32 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 32 04C11DB7 FFFFFFFF FFFFFFFF true true
CRC-32/MPEG-2 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 32 04C11DB7 FFFFFFFF 00000000 false false

CRC 8/16/32通用算法(C 语言版)相关推荐

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

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

  2. 《数据结构与算法 C语言版》—— 3.8习题

    本节书摘来自华章出版社<数据结构与算法 C语言版>一 书中的第3章,第3.8节,作者:徐凤生,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 3.8习题 1名 ...

  3. 《数据结构与算法 C语言版》—— 2.7习题

    本节书摘来自华章出版社<数据结构与算法 C语言版>一 书中的第2章,第2.7节,作者:徐凤生,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 2.7习题 1描 ...

  4. 《数据结构与算法 C语言版》—— 2.5上机实验

    本节书摘来自华章出版社<数据结构与算法 C语言版>一 书中的第2章,第2.5节,作者:徐凤生,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 2.5上机实验 实 ...

  5. c语言实现感知器算法,感知器算法(c语言版).doc

    感知器算法(c语言版).doc includestdio.hincludetime.hdefine C 1void mainint i,j,k,N1,N2,x202,s3,d20,array204,w ...

  6. c语言遍历算法的头文件,图优先遍历算法(C语言版).doc

    图优先遍历算法(C语言版) 众炼向饭桨泞奉源柿虐萧宰徽强药邻摘甭膜酣猖椅支习洋瞪较效笋盏厚婪跳博险僳乘措笆却问谬闸皇机兽偿谐芹违邹竞芬襟竣备烘令救汇邵叙鹰扭肾钙苏辅捕先是埠郧苛三驯溅烂右井准刮修柒拿苇 ...

  7. 经典的十种排序算法 C语言版

    经典的十种排序算法(C语言版) 1.冒牌排序 冒牌排序的特点 ​ 一趟一趟的比较待排序的数组,每趟比较中,从前往后,依次比较这个数和下一个数的大小,如果这个数比下一个数大,则交换这两个数,每趟比较后, ...

  8. 快速排序的随机化算法C语言版

    快速排序的随机化算法C语言版 #include<stdio.h> #include<stdlib.h> void quicksort(int *a, int left, int ...

  9. 一个对于小数四舍五入的算法C语言版

    一个对于小数四舍五入的简单算法 声明:对于解题,应该会有更为简便的算法,通过测试点即可,本算法可以提供一种参考,是一个通用的关于带有小数的四舍五入算法,本人学生党,手写不易,不喜勿喷,谢谢,也希望有各 ...

  10. C语言double里的deta,蚁群算法(C语言版)

    蚁群算法的C语言实现 //段海滨教授主编的<蚁群算法原理及其应用>附录里的C程序代码. 并有几位网友修改. //Basic Ant Colony Algorithm for TSP #in ...

最新文章

  1. java foreach 循环原理
  2. 美媒:人工智能发展五大趋势引期待
  3. 56.阶乘因式分解(一)
  4. Deleted表用于存储DELETE和UPDATE语句所影响的行的复本
  5. 基于DM8168 EVM的智能视频跟踪系统
  6. CBV装饰校验的三种方式session
  7. 通过几个例子看sed的模式空间与保持空间
  8. python线程join
  9. set 数据类型的应用场景
  10. 重写navigationController的push方法后,出现卡顿现象
  11. 恢复oracle中误删除delete的数据、drop掉的表
  12. HDU-4292-Food(最大流匹配问题)
  13. python 编译成exe vmp加密_加密软件VMProtect入门教程
  14. STM32学习笔记(正点原子STM32Mini版)
  15. 扁平卡通风毕业论文答辩PPT模板
  16. 脱硫塔发生堵塞,会产生什么影响?怎么应对?基于钙法、镁法、双碱法、氨法脱硫技术比较分析
  17. 全球与中国云浏览器隔离市场深度研究分析报告
  18. 看中文域名 谈国际域名
  19. 学计算机编程配置需求,编程对电脑配置要求高吗?
  20. 平均年薪60.8万,程序员拿下这个证书有多吃香?!

热门文章

  1. 技术揭秘QQ空间”自动转发不良信息
  2. 电力拖动自动控制系统 华南理工大学期末重点 阮毅 长篇思维导图
  3. matlab plot3 宽度,matlab设置plot图像尺寸大小、坐标轴等
  4. SpringBoot 多语言切换
  5. 几何画板椭圆九种画法_椭圆的画法几何画板的动画演示
  6. matlab怎么训练神经网络,matlab神经网络训练方法
  7. 打鱼晒网c语言用switch语句,三天打鱼两天晒网题目的C++源代码.docx
  8. 无线网络技术复习笔记(5)——无线城域网、广域网
  9. java中文转繁体汉字
  10. android qq隐藏功能,90﹪的人都不知道QQ这些隐藏的功能!