C语言实现CRC校验

C语言实现CRC校验

要实现C语言中的CRC校验,你可以按照以下步骤进行操作:

  1. 首先,确定所使用的CRC算法和参数(比如CRC-16、CRC-32等)以及多项式(生成多项式)的值。

  2. 创建一个CRC查找表(Table),用于存储预先计算好的CRC值。根据所选择的CRC算法和参数,表格的大小会有所不同。

  3. 给定待校验的数据(比如一个字节数组),初始化一个CRC寄存器为初始值(通常为全1或全0)。

  4. 对每个字节进行以下操作:
    a) 将当前字节与CRC寄存器的最高位对齐。
    b) 通过查找表,将CRC寄存器的值与当前字节进行XOR运算。
    c) 将CRC寄存器向左移动一个字节,并将结果与查找表中的值进行XOR运算。

  5. 处理完所有字节后,CRC寄存器中的值即为校验结果。

下面是一个简单的示例代码,演示了如何实现CRC-16校验:

#include 

unsigned short crc16_ccitt(unsigned char *data, int len) {
    unsigned short crc = 0xFFFF;
    unsigned short lookup_table[256] = {
        // CRC-16/CCITT lookup table
        // ...
    };

    for (int i = 0; i < len; i++) {
        crc = (crc << 8) ^ lookup_table[(crc >> 8) ^ data[i]];
    }

    return crc;
}

int main() {
    unsigned char data[] = {0x12, 0x34, 0x56, 0x78};
    int data_len = sizeof(data) / sizeof(data[0]);

    unsigned short crc = crc16_ccitt(data, data_len);
    printf("CRC-16 result: %04X\n", crc);

    return 0;
}

对于16位循环冗余效验(CRC-16),CRC结果为单字,其低字节在前,高字节在后。其生成步骤大致如下:

  1. 设置一个16位的CRC寄存器,并赋以初值0xFFFF

  2. 将数据帧中的第一个字节,与CRC寄存器的低8位按位异或,并保存在CRC寄存器中

  3. 将CRC寄存器右移1位,并检测移出的最低位是否为1,如果最低位为1,则将CRC寄存器与固定数0xA001异或

  4. 重复步骤3共8次

  5. 对数据帧的下一个字节重复步骤2,3,4,直到数据域的最后一个数据

  6. 最后的CRC寄存器中的内容,就是最后的效验值,将其附加在数据帧的最后一个数据之后,并保持低8位在前,高8位在后的放置。

#include 
typedef unsigned short Uint16;
int main()
{   Uint16 crc;
    crc=0xffff;
    char a[6]={0x01,0x03,0x00,0x00,0x00,0x0a};
    char *buf;
    buf=&a[0];
    unsigned char i,j,check;
    for( i=0; i<6; i++)
    {
        crc =crc^*buf;
        for(j=0; j<8; j++)
        {
            check = crc&1;
            crc = crc>>1;
            crc = crc&0x7fff;
            if(check) crc =crc^0xa001;
        }
        buf++; 
    }
      printf("%x",crc);
 return 0; 
}

要实现C语言中的CRC-32校验,你可以按照以下步骤进行操作:

  1. 首先,确定使用的CRC算法和参数,这里是CRC-32。

  2. 创建一个CRC查找表(Table),用于存储预先计算好的CRC值。根据所选择的CRC算法和参数,表格的大小会有所不同。

  3. 给定待校验的数据(比如一个字节数组),初始化一个CRC寄存器为初始值(通常为全1或全0)。

  4. 对每个字节进行以下操作:
    a) 将当前字节与CRC寄存器的最高位对齐。
    b) 通过查找表,将CRC寄存器的值与当前字节进行XOR运算。
    c) 将CRC寄存器向左移动一个字节,并将结果与查找表中的值进行XOR运算。

  5. 处理完所有字节后,CRC寄存器中的值即为校验结果。

下面是一个简单的示例代码,演示了如何实现CRC-32校验:

#include 

unsigned int crc32(unsigned char *data, int len) {
    unsigned int crc = 0xFFFFFFFF;
    unsigned int lookup_table[256] = {
        // CRC-32 lookup table
        // ...
    };

    for (int i = 0; i < len; i++) {
        crc = (crc >> 8) ^ lookup_table[(crc ^ data[i]) & 0xFF];
    }

    return ~crc;
}

int main() {
    unsigned char data[] = {0x12, 0x34, 0x56, 0x78};
    int data_len = sizeof(data) / sizeof(data[0]);

    unsigned int crc = crc32(data, data_len);
    printf("CRC-32 result: %08X\n", crc);

    return 0;
}

CRC-32常用(事实标准)检验函数针对能够从硬件上进行比特流实时计算而设计,即每个数据的一位进来后马上就能进行CRC-32,而不必收全数据再计算。因此对应的软件CRC-32存在一些特点:

初始值预设为0xFFFFFFFF
针对数据字节的低位先传输场景,因此数据字节的低位是高优先处理的
按照字节分段进行CRC-32计算,字节放在寄存器的低字节,因此字节最低位在左高由低的最右边一位,在进行CRC计算过程时,要从最低位/最右侧位置开始判断,移位时向右移出。因为校验码高冥端也要相应对齐,所以检验码也就要做倒位序,如0x04C11DB7(0000 0100 1100 0001 0001 1101 1011 0111)倒序为了0xEDB88320(1110 1101 1011 1000 1000 0011 0010 0000)
输出异或0xFFFFFFFF
CRC-32常用(事实标准)校验函数为反向算法(反向算法是从由右向左计算,也即计算过程中移位时,向右移出。)

uint32_t PY_CRC_32_M(uint8_t *di, uint32_t len)
{
    uint32_t crc_poly = 0xEDB88320;  //Inversion bit sequence of 0x04C11DB7
	uint32_t data_t = 0xFFFFFFFF; //initial value

	for(uint32_t i=0; i 0; --j)
        {
        	data_t = (data_t >> 1) ^ ((data_t & 1)? crc_poly: 0);
        }
	}
	return data_t ^ 0xFFFFFFFF;
}

你可能感兴趣的:(C语言,c语言,开发语言)