首先是crc的计算过程
//计算CRC
1.先要知道多项式是什么样子,
以这个IEEE802.3标准CRC32多项式为例:x32 + x26 + x23 + x22 + x16 + x12 + x11
+ x10 + x8 + x7 + x5 + x4 + x2 + x+ 1
2.转换成一个值 (通过这个初值可以生成crc多项式对应的数组表)
x32 则对应32bit = 1, x26
则对应26bit=1,得出一个值:(1<<32)|(1<<26)|(1<<23)|(1<<22)|...|(1<<1)|(1)=0x104C11DB7,
对于CRC32取低32位,则=0x4C11DB7
3.用这个值通过一定方法生成长度为256的码表,对于CRC32表内每个元素都为32bit.
4.用一定的方法查表得出CRC32值。
一下举两个例子, 例子1:
/*
多项式 c(x) = x^24+ x^23+ x^6+ x^5+ x + 1 */
二进制 0000 0000 0000 0000 0000 0000 0000 0000
0000 0001
1000 0000
0000 0000
0110 0011
计算初值:0x800063
crc24初值(0~23bit) = 0x000063
*/
接下来是使用公式计算:
static uint32_t table[256];
//位逆转
static uint32_t bitrev(uint32_t input, int bw) {
int i;
uint32_t var;
var = 0;
for (i = 0; i < bw; i++) {
if (input & 0x01) {
var |= 1 << (bw - 1 - i);
}
input >>= 1;
}
return var;
}
void crc24_init(uint32_t poly) {
int i;
int j;
uint32_t c;
poly = bitrev(poly, 24) & 0x00FFFFFF;
printf("poly:%08x\n",poly);
for (i = 0; i < 256; i++) {
c = i;
for (j = 0; j < 8; j++) {
c = (c & 1) ? (poly ^ (c >> 1)) : (c >> 1);
}
table[i] = c;
if ((i + 1) % 8 == 0) {
printf(" 0x%08x\n", c);
} else {
printf(" 0x%08x", c);
}
}
}
uint32_t crc24(uint32_t crc, void* input, int len) {
int i;
uint8_t index;
uint8_t* p;
p = (uint8_t*)input;
for (i = 0; i < len; i++) {
index = (*p ^ crc);
crc = (crc >> 8) ^ table[index];
p++;
}
return crc & 0x00FFFFFF;
}
调用方法:
crc24_init(0x800063);/* 生成表 */
crc = crc24(0x00FFFFFF, data, 10);
printf("CRC24_2 = 0x%08X\n", crc);
例子2(crc32):
/*
IEEE802.3标准CRC32多项式多项式 : x32 + x26 + x23 + x22 + x16 + x12 + x11
+ x10 + x8 + x7 + x5 + x4 + x2 + x+ 1
CRC32取低32位,则:
初始值=0x4C11DB7
*/
static uint32_t table[256];
static uint32_t bitrev(uint32_t input, int bw) {
int i;
uint32_t var;
var = 0;
for (i = 0; i < bw; i++) {
if (input & 0x01) {
var |= 1 << (bw - 1 - i);
}
input >>= 1;
}
return var;
}
void crc32_init(uint32_t poly) {
int i;
int j;
uint32_t c;
poly = bitrev(poly, 32);
for (i = 0; i < 256; i++) {
c = i;
for (j = 0; j < 8; j++) {
c = (c & 1) ? (poly ^ (c >> 1)) : (c >> 1);
}
table[i] = c;
if ((i + 1) % 8 == 0) {
printf(" 0x%08x\n", c);
} else {
printf(" 0x%08x", c);
}
}
}
uint32_t crc32(uint32_t crc, void* input, int len) {
int i;
uint8_t index;
uint8_t* p;
p = (uint8_t*)input;
for (i = 0; i < len; i++) {
index = (*p ^ crc);
crc = (crc >> 8) ^ table[index];
p++;
}
return crc ^ 0xFFFFFFFF; /* 正常的计算都是直接取 return crc & 0x00FFFFFF; 这个是协议处理用比较特殊,一般用法直接用return crc & 0x00FFFFFF;即可*/
}
调用同crc24计算:
crc32_init(0x4C11DB7);/* 生成表 */
crc = crc32(initial_value, data, 10);
printf("CRC32_2 = 0x%08X\n", crc);
测试源码附件: 点我去下载
如不能下载留言邮箱发送.