CRC16校验程序-C语言
- 格式:doc
- 大小:22.50 KB
- 文档页数:2
CRC校验C语言实现,转载请注明出处,谢谢CRC(Cyclic Redundancy Check)校验应用较为广泛,以前为了处理简单,在程序中大多数采用LRC(Longitudinal Redundancy Check)校验,LRC校验很好理解,编程实现简单。
用了一天时间研究了CRC的C语言实现,理解和掌握了基本原理和C语言编程。
结合自己的理解简单写下来。
1、CRC简介CRC检验的基本思想是利用线性编码理论,在发送端根据要传送的k位二进制码序列,以一定的规则产生一个检验码r位(就是CRC码),附在信息后面,构成一个新的二进制码序列数共(k+r)位,最后发送出去。
接收端根据同样的规则校验,以确定传送中是否出错。
接收端有两种处理方式:1、计算k位序列的CRC码,与接收到的CRC比较,一致则接收正确。
2、计算整个k+r位的CRC码,若为0,则接收正确。
CRC码有多种检验位数,8位、16位、32位等,原理相同。
16位的CRC码产生的规则是先将要发送的二进制序列数左移16位(即乘以2的16次方后),除以一个多项式,最后所得到的余数就是CRC码。
求CRC码所采用的是模2运算法则,即多项式除法中采用不带借位的减法运算,运算等同于异或运算。
这一点要仔细理解,是编程的基础。
CRC-16: (美国二进制同步系统中采用) G(X) = X16 + X15 + X2 + 1CRC-CCITT: (由欧洲CCITT推荐) G(X) = X16 + X12 + X5 + 1CRC-32: G(X) = X32 + X26 + X23 + X22 + X16 +X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + 12、按位计算CRC采用CRC-CCITT多项式,多项式为0x11021,C语言编程时,参与计算为0x1021,这个地方得深入思考才能体会其中的奥妙,分享一下我的思路:当按位计算CRC时,例如计算二进制序列为1001 1010 1010 1111时,将二进制序列数左移16位,即为1001 1010 1010 1111 (0000 0000 0000 0000),实际上该二进制序列可拆分为1000 0000 0000 0000 (0000 0000 0000 0000) + 000 0000 0000 0000 (0000 0000 0000 0000) + 00 0000 0000 0000 (0000 0000 0000 0000) + 1 0000 0000 0000 (0000 0000 0000 0000) + ……现在开始分析运算:<1>对第一个二进制分序列求余数,竖式除法即为0x10000 ^ 0x11021运算,后面的0位保留;<2>接着对第二个二进制分序列求余数,将第一步运算的余数*2后再和第二个二进制分序列一起对0x11021求余,这一步理解应该没什么问题。
C语言实现CRC16校验1.定义CRC16多项式和初始化值:CRC16校验使用的多项式可以是多种不同的值,常用的是0x8005、此外,需要定义一个初始值,初值可为0xFFFF。
```c#define CRC16_POLY 0x8005#define CRC16_INIT 0xFFFF```2.实现CRC16计算函数:根据CRC16校验算法,需要对输入数据的每个字节进行计算,不断更新CRC16值,最终得到校验结果。
```cunsigned short crc16(unsigned char *data, int length)unsigned short crc = CRC16_INIT;int i, j;for (i = 0; i < length; i++)crc ^= (unsigned short) data[i] << 8;for (j = 0; j < 8; j++)if (crc & 0x8000)crc = (crc << 1) ^ CRC16_POLY;} elsecrc = crc << 1;}}}return crc;```3.调用CRC16计算函数:将需要校验的数据传递给CRC16计算函数,并得到校验结果。
```cint mai//示例数据unsigned char data[] = {0x01, 0x02, 0x03, 0x04, 0x05};int length = sizeof(data) / sizeof(data[0]);//计算CRC16校验值unsigned short crc = crc16(data, length);//打印结果printf("CRC16校验值为:%04X\n", crc);return 0;```以上就是一个简单的C语言实现CRC16校验的代码。
请注意,这只是一个实现的简化版本,对于更复杂的数据校验场景,可能需要更多的处理。
crc16 citt false c语言CRC16是一种常用的循环冗余校验算法,它可以用于检测和纠正数据传输中的错误。
在C语言中,我们可以使用CRC16算法来计算校验和,并判断数据的完整性。
CRC16算法采用的是多项式除法,具体的计算过程如下:1. 首先,我们需要定义一个16位的CRC寄存器,初始值为0xFFFF。
2. 然后,我们将待校验的数据按位进行处理,从高位到低位逐个与CRC寄存器进行异或运算。
3. 接着,我们将CRC寄存器的值右移一位,如果最低位是1,则将寄存器与一个预设的固定值(0xA001)进行异或运算。
4. 重复上述步骤,直到所有的数据位都被处理完毕。
5. 最后,CRC寄存器的值就是计算得到的校验和。
在C语言中,我们可以通过编写一个函数来实现CRC16的计算。
下面是一个示例代码:```c#include <stdio.h>#include <stdint.h>uint16_t crc16(uint8_t *data, int length){uint16_t crc = 0xFFFF;for (int i = 0; i < length; i++) {crc ^= (uint16_t)data[i];for (int j = 0; j < 8; j++) {if (crc & 0x0001) {crc = (crc >> 1) ^ 0xA001;} else {crc >>= 1;}}}return crc;}int main(){uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05}; int length = sizeof(data) / sizeof(data[0]);uint16_t checksum = crc16(data, length);printf("CRC16 checksum: 0x%04X\n", checksum);return 0;}```在上述代码中,我们首先定义了一个crc16函数,它接受一个指向数据数组的指针和数据的长度作为输入,返回一个16位的校验和。
CRC16(循环冗余校验码)是一种通过对数据进行多项式除法来生成校验码的方法。
它通常用于数据传输过程中的错误检测和校验,以确保数据的完整性和准确性。
CITT False CRC16 是其中一种常见的CRC16 校验码算法,它采用了 CITT 标准的多项式生成 16 位的校验码。
在 C 语言中,我们可以通过编写相应的函数来实现 CITT False CRC16 校验码的生成和验证。
本文将对 CITT False CRC16 算法进行介绍,并提供一个基于 C 语言的实现示例。
一、CITT False CRC16 算法介绍CITT False CRC16 算法采用了多项式 0x1021(x^16 + x^12 + x^5 + 1)来生成 16 位的校验码。
该算法将数据与 0x8005 进行按位异或运算,然后将结果与 0x8408 进行按位取反操作。
最终得到的余数就是 16 位的 CRC16 校验码。
该算法在数据通信领域得到了广泛的应用,因其计算速度快、效果稳定而备受青睐。
二、CITT False CRC16 算法实现在 C 语言中实现 CITT False CRC16 算法并不复杂,我们可以编写一个函数来完成 CRC16 校验码的生成和验证。
以下是一个基于 C 语言的示例代码:```c#include <stdio.h>#include <stdint.h>// 定义 CITT False CRC16 多项式#define POLY 0x1021// 计算 CRC16 校验码uint16_t crc16(uint8_t *data, uint32_t len) {uint16_t crc = 0;for (uint32_t i = 0; i < len; i++) {crc = crc ^ (data[i] << 8);for (int j = 0; j < 8; j++) {if (crc 0x8000) {crc = (crc << 1) ^ POLY;} else {crc = crc << 1;}}}return crc;}int m本人n() {// 测试数据uint8_t test_data[] = {0x01, 0x02, 0x03, 0x04, 0x05};uint32_t data_len = sizeof(test_data) / sizeof(test_data[0]);// 计算 CRC16 校验码uint16_t crc_code = crc16(test_data, data_len);printf("CRC16 校验码为:04X\n", crc_code);return 0;}```以上示例代码中,我们定义了一个 crc16 函数来计算 CITT False CRC16 校验码,同时编写了一个 m本人n 函数来调用 crc16 函数并打印结果。
CRC常见算法的C语言实现CRC(Cyclic Redundancy Check)是一种常见的数据校验算法,用于检测或校正以循环方式传输的数据中的错误。
CRC算法在通信、存储、校验等领域得到广泛应用。
以下是CRC常见算法的C语言实现示例。
1.CRC-8校验算法:```// CRC-8 polynomial: x^8+x^2+x+1 (0x07)unsigned char crc8(const unsigned char *data, unsigned int length)unsigned char crc = 0;for (unsigned int i = 0; i < length; i++)crc ^= data[i];for (unsigned int j = 0; j < 8; j++)if (crc & 0x80)crc = (crc << 1) ^ 0x07;elsecrc <<= 1;}}return crc;```2.CRC-16校验算法:```// CRC-16 polynomial: x^16+x^15+x^2+1 (0x8005)unsigned short crc16(const unsigned char *data, unsigned int length)unsigned short crc = 0;for (unsigned int i = 0; i < length; i++)crc ^= (unsigned short)data[i] << 8;for (unsigned int j = 0; j < 8; j++)if (crc & 0x8000)crc = (crc << 1) ^ 0x8005;elsecrc <<= 1;}}return crc;```3.CRC-32校验算法:```// CRC-32 polynomial: 0x04c11db7unsigned int crc32(const unsigned char *data, unsigned int length)unsigned int crc = 0xFFFFFFFF;for (unsigned int i = 0; i < length; i++)crc ^= data[i];for (unsigned int j = 0; j < 8; j++)if (crc & 1)elsecrc >>= 1;}}return ~crc;```以上是常见的CRC校验算法的C语言实现示例。
c#CRC-16MODBUS校验计算⽅法及异或校验算法⼗年河东,⼗年河西,莫欺少年穷学⽆⽌境,精益求精只要是代码,如下:///<summary>///低字节在前///</summary>///<param name="pDataBytes"></param>///<returns></returns>static byte[] CRC16LH(byte[] pDataBytes){ushort crc = 0xffff;ushort polynom = 0xA001;for (int i = 0; i < pDataBytes.Length; i++){crc ^= pDataBytes[i];for (int j = 0; j < 8; j++){if ((crc & 0x01) == 0x01){crc >>= 1;crc ^= polynom;}else{crc >>= 1;}}}byte[] result = BitConverter.GetBytes(crc);return result;}///<summary>///⾼字节在前///</summary>///<param name="pDataBytes"></param>///<returns></returns>static byte[] CRC16HL(byte[] pDataBytes){ushort crc = 0xffff;ushort polynom = 0xA001;for (int i = 0; i < pDataBytes.Length; i++){crc ^= pDataBytes[i];for (int j = 0; j < 8; j++){if ((crc & 0x01) == 0x01){crc >>= 1;crc ^= polynom;}else{crc >>= 1;}}}byte[] result = BitConverter.GetBytes(crc).Reverse().ToArray() ;return result;}还有两个供⼤家验证的byte数组,如下:List<byte> llsst = new List<byte>() {0x79,0x79,0x01,0x01,0x00,0x1C,0x01,0x90,0x00,0x01,0x28,0xC3,0xC1,0x00,0xE9,0x9E,0x00,0x00,0x00,0x00,0x52,0x85,0x00,0x01,0x11,0x8E,0x15,0x02,0xD0,0x41,0x3E,0x02,0x0B var CrcLs3t22 = CRC16LH(llsst.ToArray());var CrcLs2t25 = CRC16HL(llsst.ToArray());低字节在前的结果为:83 9A⾼字节在前的结果为:9A 83异或校验算法:public static byte XOR_Check(List<byte> pbuf){int res = 0;int len = pbuf.Count;for (int i = 0; i < len; i++){res ^= pbuf[i];}return BitConverter.GetBytes(res)[0];}@天才卧龙的博客。
1.CRC8校验程序*函数名称:generateCRC(char *data, char num)*函数功能: CRC8检验程序*输入参数:char *data:检验数据首地址char num:校验数据字节个数*返回参数:校验值*相关说明:********************************************************************/ char generateCRC(char*data,char num){char i, j, a, cy, cy1=0, crcdata, a1, a2=0, crc=0;for(j=0; j<num; j++){a = *(data + j);a1 = a;for(i = 0; i<8; i++){a = a ^ crc;cy = a & 0x01;if(cy1 != 0)crcdata = 0x80;elsecrcdata = 0;a = crc;if(cy != 0){a = a ^ 0x18;crcdata = 0x80;}elsecrcdata = 0;cy1 = a & 0x01;a >>= 1;a = crcdata | a;crc = a;if(i == 0)a = a1;elsea = a2;crcdata = a & 0x01;a >>= 1;if(crcdata != 0)a = a | 0x80;a2 = a;}}return(crc);}2.CRC16校验程序/******************************************************************* *函数名称:check16crc(unsigned char *inBuffer, unsigned int size)*函数功能: CRC16检验程序*输入参数:unsigned char *inBuffer unsigned int size:校验数据字节个数*返回参数:校验值*相关说明:********************************************************************/ unsigned int check16crc(unsigned char*inBuffer,unsigned int size){unsigned int crc;unsigned int i, j;unsigned char CRC16Lo =0xff;unsigned char CRC16Hi =0xff;//CRC registerunsigned char cl =0x01;unsigned char ch =0xA0;//0xA001unsigned char saveHi,saveLo;for(i = 0; i<size; i++){CRC16Lo = CRC16Lo ^(*(inBuffer + i));for(j=0; j<8; j++){saveHi = CRC16Hi;saveLo = CRC16Lo;CRC16Hi = CRC16Hi >>1;CRC16Lo = CRC16Lo >>1;if((saveHi &0x1)==1){CRC16Lo = CRC16Lo |0x80;}if((saveLo &0x1)==1){CRC16Hi = CRC16Hi ^ ch;CRC16Lo = CRC16Lo ^ cl;}}}crc = CRC16Lo + CRC16Hi * 256;return crc;}。
crc16校验算法c语言crc16校验算法是一种常用的数据校验方法,它可以检测出数据传输或存储过程中的错误,并提供纠错的依据。
crc16校验算法的原理是将待校验的数据看作一个多项式,用一个固定的生成多项式对其进行除法运算,得到的余数就是crc16校验码。
生成多项式的选择会影响crc16校验算法的性能,不同的应用场景可能需要不同的生成多项式。
本文主要介绍一种常用的生成多项式,即CRC-CCITT,它的二进制表示为0x1021,十六进制表示为0x11021。
本文将介绍三种实现crc16校验算法c语言的方法,分别是按位计算、按半字节计算和按单字节计算。
这三种方法的原理都是基于生成多项式对数据进行除法运算,但是具体的实现方式有所不同,各有优缺点。
下面分别介绍这三种方法,并给出相应的c语言代码。
按位计算按位计算是最直接的实现方式,它是将待校验的数据和生成多项式按位进行异或运算,得到余数。
这种方法的优点是不需要额外的存储空间,缺点是效率较低,需要循环处理每一位数据。
按位计算的c语言代码如下:#include<stdint.h>#define CRC_CCITT 0x1021//生成多项式//函数名称:crc_cal_by_bit;按位计算CRC//函数参数:uint8_t * ptr;指向发送缓冲区的首字节// uint32_t len;要发送的总字节数//函数返回值:uint16_tuint16_t crc_cal_by_bit(uint8_t*ptr, uint32_t len) {uint32_t crc =0xffff; //初始值while (len--!=0) {for (uint8_t i =0x80; i !=0; i >>=1) { //处理每一位数据crc <<=1; //左移一位if ((crc &0x10000) !=0) //如果最高位为1,则异或生成多项式crc ^=0x11021;if ((*ptr & i) !=0) //如果当前数据位为1,则异或生成多项式crc ^= CRC_CCITT;}ptr++; //指向下一个字节}uint16_t retCrc = (uint16_t)(crc &0xffff); //取低16位作为结果return retCrc;}按半字节计算按半字节计算是对按位计算的优化,它是将待校验的数据和生成多项式按半字节(4位)进行异或运算,得到余数。
CRC16C语⾔实现最近看到⼀个实现crc16的⼩程序,刚开始,不明觉厉,于是花了⼀个周末去know how。
CRC(Cyclic Redundancy Check)循环冗余校验是常⽤的数据校验⽅法。
先说说什么是数据校验。
数据在传输过程(⽐如通过⽹线在两台计算机间传⽂件)中,由于传输信道的原因,可能会有误码现象(⽐如说发送数字5但接收⽅收到的却是6),如何发现误码呢?⽅法是发送额外的数据让接收⽅校验是否正确,这就是数据校验。
最容易想到的校验⽅法是和校验,就是将传送的数据(按字节⽅式)加起来计算出数据的总和,并将总和传给接收⽅,接收⽅收到数据后也计算总和,并与收到的总和⽐较看是否相同。
如果传输中出现误码,那么总和⼀般不会相同,从⽽知道有误码产⽣,可以让发送⽅再发送⼀遍数据。
CRC校验也是添加额外数据做为校验码,这就是CRC校验码,那么CRC校验码是如何得到的呢? ⾮常简单,CRC校验码就是将数据除以某个固定的数(⽐如ANSI-CRC16中,这个数是0x18005),所得到的余数就是CRC校验码。
那这⾥就有⼀个问题,我们传送的是⼀串字节数据,⽽不是⼀个数据,怎么将⼀串数字变成⼀个数据呢?这也很简单,⽐如说2个字节B1,B2,那么对应的数就是(B1<<8)+B2;如果是3个字节B1,B2,B3,那么对应的数就是((B1<<16)+(B2<<8)+B3),⽐如数字是0x01,0x02,0x03,那么对应的数字就是0x10203;依次类推。
如果字节数很多,那么对应的数就⾮常⾮常⼤,不过幸好CRC只需要得到余数,⽽不需要得到商。
从上⾯介绍的原理我们可以⼤致知道CRC校验的准确率,在CRC8中出现了误码但没发现的概率是1/256,CRC16的概率是1/65536,⽽CRC32的概率则是1/2^32,那已经是⾮常⼩了,所以⼀般在数据不多的情况下⽤CRC16校验就可以了,⽽在整个⽂件的校验中⼀般⽤CRC32校验。