#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define POLYNOMIAL_CRC32 0x4c11db7
/* 计算CRC32校验码 */
uint32_t calc_crc32(const void *data, int len)
{
const uint8_t *p = data;
int i, j;
uint32_t temp = 0;
uint32_t temp2 = 0;
uint32_t msb;
// 填充前二分之一
if (len > 0)
temp |= p[0] << 24;
if (len > 1)
temp |= p[1] << 16;
if (len > 2)
temp |= p[2] << 8;
if (len > 3)
temp |= p[3];
// 填充到八分之七
if (len > 4)
temp2 |= p[4] << 24;
if (len > 5)
temp2 |= p[5] << 16;
if (len > 6)
temp2 |= p[6] << 8;
for (i = 7; i <= len + 6; i++)
{
if (i < len)
temp2 |= p[i]; // 每次都填充最后八分之一的空间
// 从左数第0~7位计算到左数第32~39位
// 当j=0时是从左数第0位计算到第32位, 共计33位
// 当j=1时是从左数第1位计算到第33位, 共计33位
// ...
// 当j=7时是从左数第7位计算到第39位, 共计33位
for (j = 0; j < 8; j++)
{
msb = (temp & 0x80000000);
temp <<= 1;
if (temp2 & 0x80000000)
temp |= 1;
temp2 <<= 1;
if (msb)
temp ^= POLYNOMIAL_CRC32;
}
}
return temp;
}
uint8_t invert(uint8_t data)
{
int i;
uint8_t result = 0;
for (i = 0; i < 8; i++)
{
result <<= 1;
if (data & 1)
result |= 1;
data >>= 1;
}
return result;
}
uint32_t invert32(uint32_t data)
{
uint32_t result;
result = invert((data >> 24) & 0xff);
result |= invert((data >> 16) & 0xff) << 8;
result |= invert((data >> 8) & 0xff) << 16;
result |= invert(data & 0xff) << 24;
return result;
}
/* 计算CRC32校验码(初始值0xffffffff、结果异或值0xffffffff、输入数据反转、输出数据反转) */
uint32_t calc_crc32_inv(const void *data, int len)
{
const uint8_t *p = data;
int i, j;
uint32_t temp = 0xffffffff;
uint32_t temp2 = 0;
uint32_t msb;
// 填充前二分之一
if (len > 0)
temp ^= invert(p[0]) << 24;
if (len > 1)
temp ^= invert(p[1]) << 16;
if (len > 2)
temp ^= invert(p[2]) << 8;
if (len > 3)
temp ^= invert(p[3]);
// 填充到八分之七
if (len > 4)
temp2 |= invert(p[4]) << 24;
if (len > 5)
temp2 |= invert(p[5]) << 16;
if (len > 6)
temp2 |= invert(p[6]) << 8;
for (i = 7; i <= len + 6; i++)
{
if (i < len)
temp2 |= invert(p[i]); // 每次都填充最后八分之一的空间
// 从左数第0~7位计算到左数第32~39位
// 当j=0时是从左数第0位计算到第32位, 共计33位
// 当j=1时是从左数第1位计算到第33位, 共计33位
// ...
// 当j=7时是从左数第7位计算到第39位, 共计33位
for (j = 0; j < 8; j++)
{
msb = (temp & 0x80000000);
temp <<= 1;
if (temp2 & 0x80000000)
temp |= 1;
temp2 <<= 1;
if (msb)
temp ^= POLYNOMIAL_CRC32;
}
}
return invert32(temp) ^ 0xffffffff;
}
void main()
{
char *str = "
https://zh.purasbar.com/";
int i, n;
n = strlen(str);
for (i = 0; i <= n; i++)
printf("len=%d, crc32=0x%08x, crc32_inv=0x%08x\n", i, calc_crc32(str, i), calc_crc32_inv(str, i));
}
程序运行结果:
len=0, crc32=0x00000000, crc32_inv=0x00000000
len=1, crc32=0x8aad2b2f, crc32_inv=0x916b06e7
len=2, crc32=0x181d7203, crc32_inv=0xbb954675
len=3, crc32=0x84db5ef3, crc32_inv=0xa5be4a5d
len=4, crc32=0x41e278d5, crc32_inv=0x97780db2
len=5, crc32=0x3fc883fe, crc32_inv=0x3ef665a6
len=6, crc32=0xdf46956b, crc32_inv=0x2b85c687
len=7, crc32=0xcf2d9609, crc32_inv=0x0a244191
len=8, crc32=0xe83f2f79, crc32_inv=0xfed15547
len=9, crc32=0x13b079f0, crc32_inv=0x8a9472c9
len=10, crc32=0x7b862686, crc32_inv=0x7359e881
len=11, crc32=0xe974466c, crc32_inv=0x9418081c
len=12, crc32=0x7392a791, crc32_inv=0x9692daf6
len=13, crc32=0x8821dcb2, crc32_inv=0xa625afcd
len=14, crc32=0x87ee99df, crc32_inv=0x897a643f
len=15, crc32=0x31b6b4cb, crc32_inv=0x5e58e91a
len=16, crc32=0x8bb08019, crc32_inv=0xe6326e98
len=17, crc32=0x57e0cf76, crc32_inv=0x8f8cc6e1
len=18, crc32=0x2e7b5622, crc32_inv=0x3f35e06b
len=19, crc32=0x36cd1263, crc32_inv=0xb65672ad
len=20, crc32=0xa70b55c8, crc32_inv=0xa6056b65
len=21, crc32=0x45db2e45, crc32_inv=0x3bc74fd3
len=22, crc32=0x6c872536, crc32_inv=0x10eed765
len=23, crc32=0x83e42bb7, crc32_inv=0xdcc98968
len=24, crc32=0x20087a6a, crc32_inv=0x3a66f237
————————————————
版权声明:本文为CSDN博主「巨大八爪鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ZLK1214/article/details/157174177