说明:CRC16/MODBUS ,CRC32 计算代码
推荐个在线CRC计算网站
http://www.ip33.com/crc.html
1:计算 CRC32 算法代码:
//计算CRC32的算法代码: uint32_t crc32(uint8_t *data, uint32_t length) { uint32_t crc = 0xFFFFFFFF; uint32_t table[256]; // 生成CRC32查找表 for (uint32_t i = 0; i < 256; i++) { uint32_t c = i; for (int j = 0; j < 8; j++) { if (c & 1) { c = 0xEDB88320 ^ (c >> 1); } else { c = c >> 1; } } table[i] = c; } // 计算CRC32 for (uint32_t i = 0; i < length; i++) { crc = table[(crc ^ data[i]) & 0xFF] ^ (crc >> 8); } return crc ^ 0xFFFFFFFF; } //测试代码 int main() { uint8_t data[] = { 0x12, 0x34, 0x56, 0x78 }; uint32_t crc = crc32(data, sizeof(data)); printf("CRC32: 0x%08X ", crc); return 0; } //输出结果 CRC32: 0x4A090E98
2.计算 CRC16 算法代码 1:
/* CRC16 余式表 */ static uint16_t crctalbeabs[] = { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 }; /*! * 功 能: CRC16校验 * param1: 指向要校验的数据的指针 * param2: 要校验的数据的长度 * retval: 校验所得到的值,uint16_t 类型 * * 说 明: 本次CRC校验为查表法,多项式为 x16+x15+x2+1(0x8005),CRC的初始值为0xFFFF */ uint16_t Crc16_C(uint8_t *ptr, uint32_t len) { uint16_t crc = 0xffff; uint32_t i; uint8_t ch; for (i = 0; i < len; i++) { ch = *ptr++; crc = crctalbeabs[(ch ^ crc) & 15] ^ (crc >> 4); crc = crctalbeabs[((ch >> 4) ^ crc) & 15] ^ (crc >> 4); } return crc; } //测试代码 int main() { uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; uint32_t crc = Crc16_C(data, sizeof(data)); printf("CRC16: 0x%04X ", crc); return 0; } //输出结果 CRC16: 0x107B
3.计算 CRC16 算法代码 2:
#include <stdio.h> #include <stdint.h> static uint16_t yl_crc16(unsigned char *buffer, uint16_t len) { uint16_t wcrc = 0XFFFF; //16位crc寄存器预置 uint8_t temp; uint16_t i = 0, j = 0; //计数 for (i = 0; i < len; i++) //循环计算每个数据 { temp = *buffer & 0X00FF; //将八位数据与crc寄存器亦或 buffer++; //指针地址增加,指向下个数据 wcrc ^= temp; //将数据存入crc寄存器 for (j = 0; j < 8; j++) //循环计算数据的 { if (wcrc & 0X0001) //判断右移出的是不是1,如果是1则与多项式进行异或。 { wcrc >>= 1; //先将数据右移一位 wcrc ^= 0XA001; //与上面的多项式进行异或 } else //如果不是1,则直接移出 { wcrc >>= 1; //直接移出 } } } return wcrc; } int main() { unsigned char data[] = {0x12, 0x34, 0x56, 0x78}; int len = sizeof(data) / sizeof(data[0]); uint16_t crc = yl_crc16(data, len); printf("CRC16: 0x%04X ", crc); return 0; } //输出结果 CRC16: 0x107B