当前位置: 首页>編程日記>正文

CRC 8/16/32通用算法(C 语言版)

CRC 8/16/32通用算法(C 语言版)

计算原理



函数接口

只需要知道所需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/MODBUSx16 + x15 + x2 + 1168005FFFF0000truetrue

接口使用方法如下

#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/ITUx4 + x + 14030000truetrue
CRC-5/EPCx5 + x3 + 15090900falsefalse
CRC-5/ITUx5 + x4 + x2 + 15150000truetrue
CRC-5/USBx5 + x2 + 15051F1Ftruetrue
CRC-6/ITUx6 + x + 16030000truetrue
CRC-7/MMCx7 + x3 + 17090000falsefalse
CRC-8x8 + x2 + x + 18070000falsefalse
CRC-8/ITUx8 + x2 + x + 18070055falsefalse
CRC-8/ROHCx8 + x2 + x + 1807FF00truetrue
CRC-8/MAXIMx8 + x5 + x4 + 18310000truetrue
CRC-16/IBMx16 + x15 + x2 + 116800500000000truetrue
CRC-16/MAXIMx16 + x15 + x2 + 11680050000FFFFtruetrue
CRC-16/USBx16 + x15 + x2 + 1168005FFFFFFFFtruetrue
CRC-16/MODBUSx16 + x15 + x2 + 1168005FFFF0000truetrue
CRC-16/CCITTx16 + x12 + x5 + 116102100000000truetrue
CRC-16/CCITT-FALSEx16 + x12 + x5 + 1161021FFFF0000falsefalse
CRC-16/X25x16 + x12 + x5 + 1161021FFFFFFFFtruetrue
CRC-16/XMODEMx16 + x12 + x5 + 116102100000000falsefalse
CRC-16/DNPx16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1163D650000FFFFtruetrue
CRC-32x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 13204C11DB7FFFFFFFFFFFFFFFFtruetrue
CRC-32/MPEG-2x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 13204C11DB7FFFFFFFF00000000falsefalse


https://www.fengoutiyan.com/post/15565.html

相关文章:

  • 倒C角的算法
  • C和A的算法
  • C描述算法
  • C阶乘算法
  • 位置式pid算法C代码
  • C的计算
  • 概率论中C的算法
  • c语言编程计算
  • 鏡像模式如何設置在哪,圖片鏡像操作
  • 什么軟件可以把圖片鏡像翻轉,C#圖片處理 解決左右鏡像相反(旋轉圖片)
  • 手機照片鏡像翻轉,C#圖像鏡像
  • 視頻鏡像翻轉軟件,python圖片鏡像翻轉_python中鏡像實現方法
  • 什么軟件可以把圖片鏡像翻轉,利用PS實現圖片的鏡像處理
  • 照片鏡像翻轉app,java實現圖片鏡像翻轉
  • 什么軟件可以把圖片鏡像翻轉,python圖片鏡像翻轉_python圖像處理之鏡像實現方法
  • matlab下載,matlab如何鏡像處理圖片,matlab實現圖像鏡像
  • 圖片鏡像翻轉,MATLAB:鏡像圖片
  • 鏡像翻轉圖片的軟件,圖像處理:實現圖片鏡像(基于python)
  • canvas可畫,JavaScript - canvas - 鏡像圖片
  • 圖片鏡像翻轉,UGUI優化:使用鏡像圖片
  • Codeforces,CodeForces 1253C
  • MySQL下載安裝,Mysql ERROR: 1253 解決方法
  • 勝利大逃亡英雄逃亡方案,HDU - 1253 勝利大逃亡 BFS
  • 大一c語言期末考試試題及答案匯總,電大計算機C語言1253,1253《C語言程序設計》電大期末精彩試題及其問題詳解
  • lu求解線性方程組,P1253 [yLOI2018] 扶蘇的問題 (線段樹)
  • c語言程序設計基礎題庫,1253號C語言程序設計試題,2016年1月試卷號1253C語言程序設計A.pdf
  • 信奧賽一本通官網,【信奧賽一本通】1253:抓住那頭牛(詳細代碼)
  • c語言程序設計1253,1253c語言程序設計a(2010年1月)
  • 勝利大逃亡英雄逃亡方案,BFS——1253 勝利大逃亡
  • 直流電壓測量模塊,IM1253B交直流電能計量模塊(艾銳達光電)
  • c語言程序設計第三版課后答案,【渝粵題庫】國家開放大學2021春1253C語言程序設計答案
  • 18轉換為二進制,1253. 將數字轉換為16進制
  • light-emitting diode,LightOJ-1253 Misere Nim
  • masterroyale魔改版,1253 Dungeon Master
  • codeformer官網中文版,codeforces.1253 B
  • c語言程序設計考研真題及答案,2020C語言程序設計1253,1253計算機科學與技術專業C語言程序設計A科目2020年09月國家開 放大學(中央廣播電視大學)
  • c語言程序設計基礎題庫,1253本科2016c語言程序設計試題,1253電大《C語言程序設計A》試題和答案200901
  • 肇事逃逸車輛無法聯系到車主怎么辦,1253尋找肇事司機