前言
本文承接CRC16校验算法及C语言实现,继续实现CRC32的校验算法。
1、CRC32校验算法
多项式及初始值定义:
#define POLYNOMIAL 0x04C11DB7
#define POLY_INIT 0xFFFFFFFF
#define POLY_END 0x00000000
通用算法:
uint32_t crc32(unsigned char *ptr, unsigned char len,uint8_t input_invert)
{
unsigned char i;
uint32_t crc=POLY_INIT; /* 计算的初始crc值 */
const uint32_t polynomial= POLYNOMIAL;
while(len--)
{
if(input_invert)
{
crc ^= (uint32_t)(*ptr++);
for (i=8; i>0; --i) /* 下面这段计算过程与计算一个字节crc一样 */
{
if (crc & 0x00000001)
crc = (crc >> 1) ^ (uint32_t)reverse_bits(polynomial,32);
else
crc = (crc >> 1);
}
//printf("0x%.8x, ", crc); /*依次计算每个字节的crc校验值*/
}else
{
crc ^= ((uint32_t)(*ptr++)<<24);
for (i=8; i>0; --i) /* 下面这段计算过程与计算一个字节crc一样 */
{
if (crc & 0x80000000)
crc = (crc << 1) ^ polynomial;
else
crc = (crc << 1);
}
printf("0x%.8x, ", crc); /*依次计算每个字节的crc校验值*/
}
}
crc=crc^POLY_END;
return (crc);
}
按位翻转函数:
uint32_t reverse_bits(uint32_t num, int num_bits) {
uint32_t result = 0;
int i;
for (i = 0; i < num_bits; i++) {
result = (result << 1) | (num & 1);
num >>= 1;
}
return result;
}
2、CRC32的查表表格生成及使用
元素生成:
uint32_t crc32_cal_table(unsigned char value,uint8_t input_invert)
{
unsigned char i;
uint32_t crc=POLY_INIT;
const uint32_t polynomial= POLYNOMIAL;
if(input_invert)
{
crc = (uint32_t)value;
for (i=8; i>0; --i)
{
if (crc & 0x00000001)
crc = (crc >> 1) ^ (uint32_t)reverse_bits(polynomial,32);
else
crc = (crc >> 1);
}
}else
{
crc = (((uint32_t)value)<<24);
for (i=8; i>0; --i)
{
if (crc & 0x80000000) /* 判断最高位是否为1 */
crc = (crc << 1) ^ polynomial;
else
crc = (crc << 1);
}
}
crc=crc^POLY_END;
return crc;
}
表格生成(完整表格):
void create_crc32_table(void)
{
unsigned short i;
unsigned char j;
printf("const uint32_t crc32_table[256] =\n{");
for (i=0; i<=0xFF; i++)
{
if (0 == (i%8))
printf("\n");
j = i&0xFF;
printf("0x%.8x, ", crc32_cal_table (j,1)); /*依次计算每个字节的crc校验值*/
if(i==0xFF){
printf("\n");
break;
}
}
printf("};");
}
通过查表计算校验:
uint32_t cal_crc_table(unsigned char *ptr, unsigned char len,uint8_t input_invert)
{
uint32_t crc = POLY_INIT;
while (len--)
{
if(input_invert)
crc = (crc >> 8) ^ crc32_table[(crc ^ (*ptr++)) & 0xFF];
else
crc = (crc << 8) ^ crc32_table[((crc>>24) ^(*ptr++)) & 0xFF];
}
return (crc);
}
以上算法均使用工具验证过。
到此CRC8、CRC16、CRC32的算法实现完毕。
完整的PDF文档下载地址:https://download.csdn.net/download/qq_28149763/88552040