文章目录
C语言实现代码如下:
其中包括crc8、crc16、crc32的直接计算法、查表法:
bash
#include <stdint.h>
#include <stddef.h>
/* ==================== CRC-8 (MAXIM/DOW) ====================
多项式: x^8 + x^2 + x + 1 -> 0x07 (二进制 0000 0111)
初始值: 0x00
结果异或: 0x00
输入/输出反转: 否
========================================================= */
#define CRC8_POLY 0x07
#define CRC8_INIT 0x00
#define CRC8_XOROUT 0x00
/* ==================== CRC-16 (XMODEM / CCITT) ====================
多项式: x^16 + x^12 + x^5 + 1 -> 0x1021
初始值: 0x0000
结果异或: 0x0000
输入/输出反转: 否 (常用于 XMODEM)
=============================================================== */
#define CRC16_POLY 0x1021
#define CRC16_INIT 0x0000
#define CRC16_XOROUT 0x0000
/* ==================== CRC-32 (以太网 / ZIP) ====================
多项式: 0x04C11DB7 (标准以太网多项式)
初始值: 0xFFFFFFFF
结果异或: 0xFFFFFFFF
输入反转: 是 (每字节 bit 顺序反转)
输出反转: 是 (最终结果 bit 顺序反转)
============================================================== */
#define CRC32_POLY 0x04C11DB7UL
#define CRC32_INIT 0xFFFFFFFFUL
#define CRC32_XOROUT 0xFFFFFFFFUL
/* crc-8 直接计算法(按位) */
/* function: 直接计算法 */
uint8_t crc8_direct(const uint8_t *data, size_t len) {
uint8_t crc = CRC8_INIT;
for (size_t i = 0; i < len; i++) {
crc ^= data[i];
for (int bit = 0; bit < 8; bit++) {
if (crc & 0x80) {
crc = (crc << 1) ^ CRC8_POLY;
} else {
crc <<= 1;
}
}
}
return crc ^ CRC8_XOROUT;
}
/* crc-8 查表法 */
/* function: 先预生成 256 项的表 */
uint8_t crc8_table[256];
void crc8_table_init(void) {
for (int i = 0; i < 256; i++) {
uint8_t crc = (uint8_t)i;
for (int bit = 0; bit < 8; bit++) {
if (crc & 0x80)
crc = (crc << 1) ^ CRC8_POLY;
else
crc <<= 1;
}
crc8_table[i] = crc;
}
}
/* function:查表计算 */
uint8_t crc8_table_calc(const uint8_t *data, size_t len) {
uint8_t crc = CRC8_INIT;
for (size_t i = 0; i < len; i++) {
crc = crc8_table[crc ^ data[i]];
}
return crc ^ CRC8_XOROUT;
}
/* crc-16 直接计算法(按位) */
/* function: 直接计算法 */
uint16_t crc16_direct(const uint8_t *data, size_t len) {
uint16_t crc = CRC16_INIT;
for (size_t i = 0; i < len; i++) {
crc ^= (uint16_t)data[i] << 8; // 数据与高8位异或
for (int bit = 0; bit < 8; bit++) {
if (crc & 0x8000) {
crc = (crc << 1) ^ CRC16_POLY;
} else {
crc <<= 1;
}
}
}
return crc ^ CRC16_XOROUT;
}
/* crc-16 查表法 */
/* function: 先预生成 256 项的表 */
uint16_t crc16_table[256];
void crc16_table_init(void) {
for (int i = 0; i < 256; i++) {
uint16_t crc = (uint16_t)i << 8;
for (int bit = 0; bit < 8; bit++) {
if (crc & 0x8000)
crc = (crc << 1) ^ CRC16_POLY;
else
crc <<= 1;
}
crc16_table[i] = crc;
}
}
/* function: 查表计算 */
uint16_t crc16_table_calc(const uint8_t *data, size_t len) {
uint16_t crc = CRC16_INIT;
for (size_t i = 0; i < len; i++) {
uint8_t index = (uint8_t)(crc >> 8) ^ data[i];
crc = (crc << 8) ^ crc16_table[index];
}
return crc ^ CRC16_XOROUT;
}
/* crc-32 (标准以太网风格,含位反转) */
/* function: 辅助函数:位反转(用于输入字节和最终结果) */
static uint32_t bit_reverse32(uint32_t x) {
x = ((x & 0x55555555) << 1) | ((x >> 1) & 0x55555555);
x = ((x & 0x33333333) << 2) | ((x >> 2) & 0x33333333);
x = ((x & 0x0F0F0F0F) << 4) | ((x >> 4) & 0x0F0F0F0F);
x = (x << 24) | ((x & 0xFF00) << 8) | ((x >> 8) & 0xFF00) | (x >> 24);
return x;
}
static uint8_t bit_reverse8(uint8_t x) {
x = (uint8_t)((x & 0x55) << 1) | ((x >> 1) & 0x55);
x = (uint8_t)((x & 0x33) << 2) | ((x >> 2) & 0x33);
x = (uint8_t)((x & 0x0F) << 4) | ((x >> 4) & 0x0F);
return x;
}
/* function: 直接计算法(按位,处理反转) */
uint32_t crc32_direct(const uint8_t *data, size_t len) {
uint32_t crc = CRC32_INIT;
for (size_t i = 0; i < len; i++) {
uint8_t byte = bit_reverse8(data[i]); // 输入字节位反转
crc ^= (uint32_t)byte << 24;
for (int bit = 0; bit < 8; bit++) {
if (crc & 0x80000000UL) {
crc = (crc << 1) ^ CRC32_POLY;
} else {
crc <<= 1;
}
}
}
crc = bit_reverse32(crc); // 输出结果位反转
return crc ^ CRC32_XOROUT;
}
/*查表法(4 字节表,常见实现)*/
/*function: 生成 256 项的表(每个表项已经隐含了位反转)*/
uint32_t crc32_table[256];
void crc32_table_init(void) {
for (int i = 0; i < 256; i++) {
uint32_t crc = (uint32_t)i << 24;
for (int bit = 0; bit < 8; bit++) {
if (crc & 0x80000000UL)
crc = (crc << 1) ^ CRC32_POLY;
else
crc <<= 1;
}
crc32_table[i] = crc;
}
}
/*function: 查表计算(每字节查表一次,自动处理输入反转)*/
uint32_t crc32_table_calc(const uint8_t *data, size_t len) {
uint32_t crc = CRC32_INIT;
for (size_t i = 0; i < len; i++) {
uint8_t byte = bit_reverse8(data[i]); // 每字节先反转
uint8_t index = (uint8_t)(crc >> 24) ^ byte;
crc = (crc << 8) ^ crc32_table[index];
}
crc = bit_reverse32(crc); // 输出反转
return crc ^ CRC32_XOROUT;
}
#include <stdio.h>
#include <string.h>
int main() {
const char *test = "123456789";
size_t len = strlen(test);
uint8_t *data = (uint8_t*)test;
// 初始化查表
crc8_table_init();
crc16_table_init();
crc32_table_init();
// CRC-8
printf("CRC-8 direct: 0x%02X\n", crc8_direct(data, len));
printf("CRC-8 table: 0x%02X\n", crc8_table_calc(data, len));
// CRC-16
printf("CRC-16 direct: 0x%04X\n", crc16_direct(data, len));
printf("CRC-16 table: 0x%04X\n", crc16_table_calc(data, len));
// CRC-32
printf("CRC-32 direct: 0x%08X\n", crc32_direct(data, len));
printf("CRC-32 table: 0x%08X\n", crc32_table_calc(data, len));
return 0;
}
运行结果:
bash
CRC-8 direct: 0xF4
CRC-8 table: 0xF4
CRC-16 direct: 0x31C3
CRC-16 table: 0x31C3
CRC-32 direct: 0xCBF43926
CRC-32 table: 0xCBF43926
在线工具推荐
工具1:
使用示例:

工具2:
使用示例:

多项式统计
