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;
}