CRC 校验
[toc]
一直没搞懂CRC校验,先把计算方法写出来放在这里,以后再慢慢理解吧
分为直接计算和查表法,后者性能更高
crc 8
直接计算
uint8_t poly = 0x07; // x8 + x2 + x + 1
uint8_t init = 0x00;
uint8_t out = 0x00;
uint8_t cal_crc(const uint8_t *data, int len) {
uint8_t crc = init;
for (int i = 0; i < len; i++) {
crc ^= data[i];
for (int j = 0; j < 8; j++) {
if (crc & 0x80) {
crc = (crc << 1) ^ poly;
} else {
crc = crc << 1;
}
}
}
return crc ^ out;
}
查表
uint8_t poly = 0x07; // x8 + x2 + x + 1
uint8_t init = 0x00;
uint8_t out = 0x00;
uint8_t crc_table[256];
void create_crc_table() {
for (int i = 0; i < 256; i++) {
uint8_t crc = i;
for (int j = 0; j < 8; j++) {
if (crc & 0x80) {
crc = (crc << 1) ^ poly; // 最高位为1
} else {
crc = crc << 1;
}
}
crc_table[i] = crc;
}
}
uint8_t cal_crc_table(const uint8_t *data, int len) {
uint8_t crc = init;
for (int i = 0; i < len; i++) {
crc = crc_table[crc ^ data[i]];
}
return crc ^ out;
}
crc 16
直接计算
uint16_t poly = 0x1021; // x16 + x12 + x5 + 1
uint16_t init = 0x0;
uint16_t out = 0x0;
uint16_t cal_crc(const uint8_t *data, int len) {
uint16_t crc = init;
for (int i = 0; i < len; i++) {
crc ^= data[i] << 8;
for (int j = 0; j < 8; j++) {
if (crc & 0x8000) {
crc = (crc << 1) ^ poly; // 最高位为1
} else {
crc = crc << 1;
}
}
}
return crc ^ out;
}
查表
uint16_t poly = 0x1021; // x16 + x12 + x5 + 1
uint16_t init = 0x0;
uint16_t out = 0x0;
uint16_t crc_table[256];
void create_crc_table() {
for (int i = 0; i < 256; i++) {
uint16_t crc = i;
for (int j = 0; j < 16; j++) {
if (crc & 0x8000) {
crc = (crc << 1) ^ poly; // 最高位为1
} else {
crc = crc << 1;
}
}
crc_table[i] = crc;
}
}
uint16_t cal_crc_table(const uint8_t *data, int len) {
uint16_t crc = init;
for (int i = 0; i < len; i++) {
crc = crc_table[(crc >> 8) ^ data[i]] ^ (crc << 8);
}
return crc ^ out;
}
crc 32
直接计算
// x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
uint32_t poly = 0x04c11db7;
uint32_t init = 0x0;
uint32_t out = 0x0;
uint32_t cal_crc(const uint8_t *data, int len) {
uint32_t crc = init;
for (int i = 0; i < len; i++) {
crc ^= data[i] << 24;
for (int j = 0; j < 8; j++) {
if (crc & 0x80000000) {
crc = (crc << 1) ^ poly; // 最高位为1
} else {
crc = crc << 1;
}
}
}
return crc ^ out;
}
查表
// x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
uint32_t poly = 0x04c11db7;
uint32_t init = 0x0;
uint32_t out = 0x0;
uint32_t crc_table[256];
void create_crc_table() {
for (int i = 0; i < 256; i++) {
uint32_t crc = i;
for (int j = 0; j < 32; j++) {
if (crc & 0x80000000) {
crc = (crc << 1) ^ poly; // 最高位为1
} else {
crc = crc << 1;
}
}
crc_table[i] = crc;
}
}
uint32_t cal_crc_table(const uint8_t *data, int len) {
uint32_t crc = init;
for (int i = 0; i < len; i++) {
crc = crc_table[(crc >> 24) ^ data[i]] ^ (crc << 8);
}
return crc ^ out;
}
由于个人水平有限,文中若有不合理或不正确的地方欢迎指出改正