CRC校验大全:一文掌握所有常用CRC算法

CRC校验核心原理

CRC(Cyclic Redundancy Check)通过对数据多项式进行模2除法,生成固定位数的校验码。以下是实现中的五个关键参数:

  1. Poly:生成多项式(决定校验强度)

  2. Init:初始寄存器值

  3. Refin:输入字节位反转

  4. Refout:输出结果位反转

  5. Xorout:最终异或掩码

CRC-3 校验函数

CRC-3 (直接位操作版)

应用:嵌入式寄存器

参数:Poly=0x07, Init=根据参数定, Refin=false, Refout=false

/**
 * @brief CRC-3校验(位操作实现)
 * @param data 待校验数据(需左对齐到最高位)
 * @param bitlen 数据位数(不是字节数)
 * @param poly 生成多项式(实际值需左移1位,如x³+x+1=0b1011→0x03)
 * @param crcinit 初始值(常用0x05或0x07)
 * @return 3位CRC校验值
 * @note 适用于硬件寄存器等需要逐位处理的场景
 * @example 
 *   unsigned long data = 0xB2000000; // 10110010...
 *   crc_3(data, 8, 0x03, 0x05); // 计算8位数据的CRC3
 */
unsigned long crc_3(unsigned long data, unsigned long bitlen, 
                   unsigned char poly, unsigned char crcinit) 
{
    unsigned long crc = (crcinit == 0x05) ? 0x04 : 
                       (crcinit == 0x07) ? 0x02 : 0x00;
    while (bitlen--) 
    {
        int bit = (crc >> 2) ^ (data >> 31);
        crc = (crc << 1) & 0x07;
        if (bit) crc ^= poly;
        data <<= 1;
    }
    return crc;
}

CRC-3 (x³+x+1)

应用:短帧通信校验

参数:Poly=0x03, Init=0x05, Refin=false, Refout=false, Xorout=0x00

/**
 * @brief CRC-3校验(字节流优化实现)
 * @param data 数据指针(字节数组)
 * @param length 数据长度(字节数)
 * @return CRC值(仅低3位有效)
 * @note 
 *   - 多项式: x³ + x + 1 (0x03)
 *   - 初始值: 0x07
 *   - 输出不反转
 * @example
 *   uint8_t data[] = {0x12, 0x34};
 *   uint8_t crc = crc3(data, 2); // 计算2字节CRC3
 */
unsigned char crc3(unsigned char* data, unsigned short int length) 
{
    unsigned char crc = 0x07;
    while (length--) {
        crc ^= *data++;
        for (int i = 0; i < 8; i++) 
        {
            crc = (crc & 0x80) ? (crc << 1) ^ 0x06 : (crc << 1);
        }
    }
    return crc >> 5;
}

CRC-4 校验函数

CRC-4/ITU (x⁴+x+1)

应用:E1通信线路

参数:Poly=0x03, Init=0x00, Refin=true, Refout=true, Xorout=0x00

/**
 * @brief CRC-4/ITU校验(x⁴ + x + 1)
 * @param data 数据指针
 * @param length 数据长度(字节数)
 * @return CRC值(低4位有效)
 * @note
 *   - 多项式: 0x03 (x⁴ + x + 1)
 *   - 初始值: 0x00
 *   - 输入/输出: 反转
 *   - 典型应用: ITU-T G.704标准
 * @example
 *   uint8_t data[] = {0x12, 0x34};
 *   uint8_t crc = crc4_itu(data, 2); // 应返回0xC
 */
uint8_t crc4_itu(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0x0C;
            else crc >>= 1;
        }
    }
    return crc & 0x0F;
}

CRC-5 校验函数

CRC-5/EPC (x⁵+x³+1)

应用:EPC电子标签

参数:Poly=0x09, Init=0x09, Refin=false, Refout=false, Xorout=0x00

/**
 * @brief CRC-5/EPC校验(x⁵ + x³ + 1)
 * @param data 数据指针
 * @param length 数据长度(字节数)
 * @return CRC值(低5位有效)
 * @note
 *   - 多项式: 0x48(左对齐表示)
 *   - 初始值: 0x09
 *   - 典型应用: EPC Gen2 RFID标签
 * @example
 *   uint8_t epc[] = {0x01, 0x23};
 *   uint8_t crc = crc5_epc(epc, 2);
 */
uint8_t crc5_epc(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0x48;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            crc = (crc & 0x80) ? (crc << 1) ^ 0x48 : (crc << 1);
        }
    }
    return crc >> 3;
}

CRC-5/ITU (x⁵+x⁴+x²+1)

应用:USB接口设备

参数:Poly=0x15, Init=0x00, Refin=true, Refout=true, Xorout=0x00​​​​​​​

/**
 * @brief CRC-5/ITU校验(x⁵ + x⁴ + x² + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC值(低5位有效)
 * @note
 *   - 多项式: 0x15
 *   - 初始值: 0x00
 *   - 输入/输出: 反转
 */
uint8_t crc5_itu(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0x15;
            else crc >>= 1;
        }
    }
    return crc;
}

CRC-5/USB (x⁵+x²+1)

应用:USB协议数据包

参数:Poly=0x05, Init=0x1F, Refin=true, Refout=true, Xorout=0x1F​​​​​​​

/**
 * @brief CRC-5/USB校验(x⁵ + x² + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC值(低5位有效)
 * @note
 *   - 多项式: 0x05
 *   - 初始值: 0x1F
 *   - 输出异或值: 0x1F
 *   - 典型应用: USB令牌包校验
 */
uint8_t crc5_usb(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0x1F;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0x14;
            else crc >>= 1;
        }
    }
    return crc ^ 0x1F;
}

CRC-6 校验函数

CRC-6/ITU (x⁶+x+1)

应用:电信控制信道

参数:Poly=0x03, Init=0x00, Refin=true, Refout=true, Xorout=0x00​​​​​​​

/**
 * @brief CRC-6/ITU校验(x⁶ + x + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC值(低6位有效)
 * @note
 *   - 多项式: 0x03
 *   - 初始值: 0x00
 *   - 输入/输出: 反转
 */
uint8_t crc6_itu(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0x30;
            else crc >>= 1;
        }
    }
    return crc;
}

CRC-7 校验函数

CRC-7/MMC (x⁷+x³+1)

应用:SD存储卡

参数:Poly=0x09, Init=0x00, Refin=false, Refout=false, Xorout=0x00​​​​​​​

/**
 * @brief CRC-7/MMC校验(x⁷ + x³ + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC值(低7位有效)
 * @note
 *   - 多项式: 0x09
 *   - 初始值: 0x00
 *   - 典型应用: MMC/SD卡命令校验
 * @example
 *   uint8_t cmd[] = {0x40, 0x00, 0x00, 0x00, 0x00};
 *   uint8_t crc = crc7_mmc(cmd, 5); // SD卡CMD0的CRC
 */
uint8_t crc7_mmc(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 0x80) crc = (crc << 1) ^ 0x12;
            else crc <<= 1;
        }
    }
    return crc >> 1;
}

CRC-8 校验函数

CRC-8 (x⁸+x²+x+1)

应用:基础通信协议

参数:Poly=0x07, Init=0x00, Refin=false, Refout=false, Xorout=0x00​​​​​​​

/**
 * @brief 标准CRC8校验(x⁸ + x² + x + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC8值
 * @note
 *   - 多项式: 0x07
 *   - 初始值: 0x00
 */
uint8_t crc8(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            crc = (crc & 0x80) ? (crc << 1) ^ 0x07 : (crc << 1);
        }
    }
    return crc;
}

CRC-8/ITU (x⁸+x²+x+1)

应用:ATM网络传输

参数:Poly=0x07, Init=0x00, Refin=false, Refout=false, Xorout=0x55​​​​​​​

/**
 * @brief CRC-8/ITU校验(x⁸ + x² + x + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC8值
 * @note
 *   - 多项式: 0x07
 *   - 输出异或值: 0x55
 *   - 别名: CRC-8/ATM
 */
uint8_t crc8_itu(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            crc = (crc & 0x80) ? (crc << 1) ^ 0x07 : (crc << 1);
        }
    }
    return crc ^ 0x55;
}

CRC-8/ROHC (x⁸+x²+x+1)

应用:物联网设备

参数:Poly=0x07, Init=0xFF, Refin=true, Refout=true, Xorout=0x00​​​​​​​

/**
 * @brief CRC-8/ROHC校验(x⁸ + x² + x + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC8值
 * @note
 *   - 多项式: 0x07
 *   - 初始值: 0xFF
 *   - 输入/输出: 反转
 *   - 典型应用: 实时传输协议头校验
 */
uint8_t crc8_rohc(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0xFF;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0xE0;
            else crc >>= 1;
        }
    }
    return crc;
}

CRC-8/MAXIM (x⁸+x⁵+x⁴+1)

应用:DS18B20传感器

参数:Poly=0x31, Init=0x00, Refin=true, Refout=true, Xorout=0x0

/**
 * @brief CRC-8/MAXIM校验(x⁸ + x⁵ + x⁴ + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC8值
 * @note
 *   - 多项式: 0x31
 *   - 初始值: 0x00
 *   - 输入/输出: 反转
 *   - 典型应用: DS18B20温度传感器
 */
uint8_t crc8_maxim(uint8_t *data, uint16_t length) 
{
    uint8_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0x8C;
            else crc >>= 1;
        }
    }
    return crc;
}

CRC-16 校验函数

CRC-16/IBM (x¹⁶+x¹⁵+x²+1)

应用:文件压缩

参数:Poly=0x8005, Init=0x0000, Refin=true, Refout=true, Xorout=0x0000​​​​​​​

/**
 * @brief CRC-16/IBM校验(x¹⁶ + x¹⁵ + x² + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 多项式: 0x8005
 *   - 初始值: 0x0000
 *   - 输入/输出: 反转
 *   - 别名: CRC-16/ARC, CRC-16/LHA
 */
uint16_t crc16_ibm(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0xA001;
            else crc >>= 1;
        }
    }
    return crc;
}

CRC-16/MAXIM (x¹⁶+x¹⁵+x²+1)

应用:工业传感器

参数:Poly=0x8005, Init=0x0000, Refin=true, Refout=true, Xorout=0xFFFF​​​​​​​

/**
 * @brief CRC-16/MAXIM校验(x¹⁶ + x¹⁵ + x² + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 输出异或值: 0xFFFF
 *   - 典型应用: Maxim 1-Wire总线
 */
uint16_t crc16_maxim(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0xA001;
            else crc >>= 1;
        }
    }
    return ~crc;
}

CRC-16/USB (x¹⁶+x¹⁵+x²+1)

应用:USB协议栈

参数:Poly=0x8005, Init=0xFFFF, Refin=true, Refout=true, Xorout=0xFFFF​​​​​​​

/**
 * @brief CRC-16/USB校验(x¹⁶ + x¹⁵ + x² + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 初始值: 0xFFFF
 *   - 输出异或值: 0xFFFF
 */
uint16_t crc16_usb(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0xFFFF;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0xA001;
            else crc >>= 1;
        }
    }
    return ~crc;
}

CRC-16/MODBUS (x¹⁶+x¹⁵+x²+1)

应用:工业控制器

参数:Poly=0x8005, Init=0xFFFF, Refin=true, Refout=true, Xorout=0x0000​​​​​​​

/**
 * @brief CRC-16/MODBUS校验(x¹⁶ + x¹⁵ + x² + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 初始值: 0xFFFF
 *   - 输出异或值: 0x0000
 *   - 典型应用: Modbus RTU协议
 * @example
 *   uint8_t frame[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01};
 *   uint16_t crc = crc16_modbus(frame, 6); // 应返回0x840A
 */
uint16_t crc16_modbus(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0xFFFF;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0xA001;
            else crc >>= 1;
        }
    }
    return crc;
}

CRC-16/CCITT (x¹⁶+x¹²+x⁵+1)

应用:XMODEM协议

参数:Poly=0x1021, Init=0x0000, Refin=true, Refout=true, Xorout=0x0000​​​​​​​

/**
 * @brief CRC-16/CCITT校验(x¹⁶ + x¹² + x⁵ + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 多项式: 0x1021
 *   - 初始值: 0x0000
 *   - 别名: CRC-16/KERMIT
 */
uint16_t crc16_ccitt(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0x8408;
            else crc >>= 1;
        }
    }
    return crc;
}

CRC-16/CCITT-FALSE (x¹⁶+x¹²+x⁵+1)

应用:5G通信

参数:Poly=0x1021, Init=0xFFFF, Refin=false, Refout=false, Xorout=0x0000​​​​​​​

/**
 * @brief CRC-16/CCITT-FALSE校验
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 初始值: 0xFFFF
 *   - 输入/输出: 不反转
 *   - 典型应用: Modbus ASCII协议
 */
uint16_t crc16_ccitt_false(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0xFFFF;
    while(length--) 
    {
        crc ^= (uint16_t)(*data++) << 8;
        for(int i=0; i<8; i++) 
        {
            if(crc & 0x8000) crc = (crc << 1) ^ 0x1021;
            else crc <<= 1;
        }
    }
    return crc;
}

CRC-16/X25 (x¹⁶+x¹²+x⁵+1)

应用:智能电表

参数:Poly=0x1021, Init=0xFFFF, Refin=true, Refout=true, Xorout=0xFFFF​​​​​​​

/**
 * @brief CRC-16/X25校验(x¹⁶ + x¹² + x⁵ + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 初始值: 0xFFFF
 *   - 输出异或值: 0xFFFF
 *   - 典型应用: X.25协议帧校验
 */
uint16_t crc16_x25(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0xFFFF;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++)
        {
            if(crc & 1) crc = (crc >> 1) ^ 0x8408;
            else crc >>= 1;
        }
    }
    return ~crc;
}

CRC-16/XMODEM (x¹⁶+x¹²+x⁵+1)

应用:卫星通信

参数:Poly=0x1021, Init=0x0000, Refin=false, Refout=false, Xorout=0x0000​​​​​​​

/**
 * @brief CRC-16/XMODEM校验(x¹⁶ + x¹² + x⁵ + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 初始值: 0x0000
 *   - 输入/输出: 不反转
 *   - 别名: CRC-16/ZMODEM
 */
uint16_t crc16_xmodem(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0;
    while(length--) 
    {
        crc ^= (uint16_t)(*data++) << 8;
        for(int i=0; i<8; i++) 
        {
            if(crc & 0x8000) crc = (crc << 1) ^ 0x1021;
            else crc <<= 1;
        }
    }
    return crc;
}

CRC-16/DNP(x¹⁶+x¹³+x¹²+x¹¹+x¹⁰+x⁸+x⁶+x⁵+x²+1)

应用:电网通信

参数:Poly=0x3D65, Init=0x0000, Refin=true, Refout=true, Xorout=0xFFFF

/**
 * @brief CRC-16/DNP校验(x¹⁶ + x¹³ + x¹² + x¹¹ + x¹⁰ + x⁸ + x⁶ + x⁵ + x² + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC16值
 * @note
 *   - 多项式: 0x3D65
 *   - 输出异或值: 0xFFFF
 *   - 典型应用: DNP3协议
 */
uint16_t crc16_dnp(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0xA6BC;
            else crc >>= 1;
        }
    }
    return ~crc;
}

CRC-32 校验函数

CRC-32 (x³²+x²⁶+...+1)

应用:ZIP/RAR压缩

参数:Poly=0x04C11DB7, Init=0xFFFFFFFF, Refin=true, Refout=true, Xorout=0xFFFFFFFF​​​​​​​

/**
 * @brief CRC-32校验(x³² + x²⁶ + ... + 1)
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC32值
 * @note
 *   - 多项式: 0x04C11DB7
 *   - 初始值: 0xFFFFFFFF
 *   - 输出异或值: 0xFFFFFFFF
 *   - 典型应用: ZIP/RAR/以太网帧校验
 * @example
 *   uint8_t data[] = "123456789";
 *   uint32_t crc = crc32(data, 9); // 应返回0xCBF43926
 */
uint32_t crc32(uint8_t *data, uint16_t length) 
{
    uint32_t crc = 0xFFFFFFFF;
    while(length--) 
    {
        crc ^= *data++;
        for(int i=0; i<8; i++) 
        {
            if(crc & 1) crc = (crc >> 1) ^ 0xEDB88320;
            else crc >>= 1;
        }
    }
    return ~crc;
}

CRC-32/MPEG-2 (x³²+x²⁶+...+1)

应用:数字电视

参数:Poly=0x04C11DB7, Init=0xFFFFFFFF, Refin=false, Refout=false, Xorout=0x00000000​​​​​​​

/**
 * @brief CRC-32/MPEG-2校验
 * @param data 数据指针
 * @param length 数据长度
 * @return CRC32值
 * @note
 *   - 输入/输出: 不反转
 *   - 典型应用: MPEG-2传输流
 */
uint32_t crc32_mpeg_2(uint8_t *data, uint16_t length) 
{
    uint32_t crc = 0xFFFFFFFF;
    while(length--) 
    {
        crc ^= (uint32_t)(*data++) << 24;
        for(int i=0; i<8; i++) 
        {
            if(crc & 0x80000000) crc = (crc << 1) ^ 0x04C11DB7;
            else crc <<= 1;
        }
    }
    return crc;
}

关注微信公众号「芯动视界」,解锁代码世界的核心奥秘!获取更多资料!

🔧 深耕C语言精髓:从指针迷宫到内存管理,系统化讲解,助你夯实底层基础。
⚡️ 探索嵌入式实战:剖析项目案例,分享避坑指南,让开发效率翻倍。

无论你是初无论你是初探嵌入式的新手,还是寻求进阶的老兵,这里都有你需要的硬核干货与技术洞见。一起用代码“芯”动视界!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值