海明码和CRC校验的C语言实现
CRC12_C语言实现
CRC12_C语言实现一概述CRC(Cyclical Redundancy Check)循环冗余码校验。
CRC码是数据通信领域中最常用的一种差错检验码,其特征是信息字段和校验字段的长度可以任意选定。
根据应用环境与习惯的不同,CRC又可分为以下几种标准:①CRC-12码;②②CRC-16码;③③CRC-CCITT码;④④CRC-32码。
CRC-12码通常用来传送6-bit字符串。
CRC-16及CRC-CCITT码则用是来传送8-bit字符,其中CRC-16为美国采用,而CRC-CCITT为欧洲国家所采用。
CRC-32码大都被采用在一种称为Point-to-Point的同步传输中。
二实现方法1、移位法2、查表法三 C语言案例移位法与查表法,是CRC12的具体实现形式,设计者可根据设计环境具体选择。
// 移位法CRC12校验码计算函数WORD CRC12(BYTE a cbyBuff[], int iLen){WORD wCRC;int i, iQ;BYTE iR;wCRC = 0;iQ = 0;iR = 0;while(iQ < iLen){// 多项式除法// 如果该位为1if(acbyBuff[iQ] & (0x80>>iR)){// 则在余数尾部添1否则添0wCRC |= 0x01;}// 如果12位除数中的最高位为1,则够除if(wCRC >= 0x1000){wCRC ^= 0x180D;}wCRC <<= 1;iR++;if(8 == iR){iR = 0;iQ++;}}// 对后面添加的12个0做处理for(i=0; i<12; i++){if(wCRC >= 0x1000){wCRC ^= 0x180D;}wCRC <<= 1;}wCRC >>= 1;return wCRC;}// 查表法CRC12校验码计算函数WORD TableCRC12(BYTE buff[], int len){int n;WORD Cn;BYTE ab, fg;WORD awCRC_Code[] ={0x0000, 0x080D, 0x0817, 0x001A, 0x0823, 0x002E, 0x0034, 0x0839,0x084B, 0x0046, 0x005C, 0x0851, 0x0068, 0x0865, 0x087F, 0x0072,0x089B, 0x0096, 0x008C, 0x0881, 0x00B8, 0x08B5, 0x08AF, 0x00A2,0x00D0, 0x08DD, 0x08C7, 0x00CA, 0x08F3, 0x00FE, 0x00E4, 0x08E9,0x093B, 0x0136, 0x012C, 0x0921, 0x0118, 0x0915, 0x090F, 0x0102,0x0170, 0x097D, 0x0967, 0x016A, 0x0953, 0x015E, 0x0144, 0x0949,0x01A0, 0x09AD, 0x09B7, 0x01BA, 0x0983, 0x018E, 0x0194, 0x0999,0x09EB, 0x01E6, 0x01FC, 0x09F1, 0x01C8, 0x09C5, 0x09DF, 0x01D2,0x0A7B, 0x0276, 0x026C, 0x0A61, 0x0258, 0x0A55, 0x0A4F, 0x0242,0x0230, 0x0A3D, 0x0A27, 0x022A, 0x0A13, 0x021E, 0x0204, 0x0A09,0x02E0, 0x0AED, 0x0AF7, 0x02FA, 0x0AC3, 0x02CE, 0x02D4, 0x0AD9,0x0AAB, 0x02A6, 0x02BC, 0x0AB1, 0x0288, 0x0A85, 0x0A9F, 0x0292,0x0340, 0x0B4D, 0x0B57, 0x035A, 0x0B63, 0x036E, 0x0374, 0x0B79,0x0B0B, 0x0306, 0x031C, 0x0B11, 0x0328, 0x0B25, 0x0B3F, 0x0332,0x0BDB, 0x03D6, 0x03CC, 0x0BC1, 0x03F8, 0x0BF5, 0x0BEF, 0x03E2,0x0390, 0x0B9D, 0x0B87, 0x038A, 0x0BB3, 0x03BE, 0x03A4, 0x0BA9,0x0CFB, 0x04F6, 0x04EC, 0x0CE1, 0x04D8, 0x0CD5, 0x0CCF, 0x04C2,0x04B0, 0x0CBD, 0x0CA7, 0x04AA, 0x0C93, 0x049E, 0x0484, 0x0C89,0x0460, 0x0C6D, 0x0C77, 0x047A, 0x0C43, 0x044E, 0x0454, 0x0C59,0x0C2B, 0x0426, 0x043C, 0x0C31, 0x0408, 0x0C05, 0x0C1F, 0x0412,0x05C0, 0x0DCD, 0x0DD7, 0x05DA, 0x0DE3, 0x05EE, 0x05F4, 0x0DF9,0x0D8B, 0x0586, 0x059C, 0x0D91, 0x05A8, 0x0DA5, 0x0DBF, 0x05B2,0x0D5B, 0x0556, 0x054C, 0x0D41, 0x0578, 0x0D75, 0x0D6F, 0x0562,0x0510, 0x0D1D, 0x0D07, 0x050A, 0x0D33, 0x053E, 0x0524, 0x0D29,0x0680, 0x0E8D, 0x0E97, 0x069A, 0x0EA3, 0x06AE, 0x06B4, 0x0EB9,0x0ECB, 0x06C6, 0x06DC, 0x0ED1, 0x06E8, 0x0EE5, 0x0EFF, 0x06F2,0x0E1B, 0x0616, 0x060C, 0x0E01, 0x0638, 0x0E35, 0x0E2F, 0x0622,0x0650, 0x0E5D, 0x0E47, 0x064A, 0x0E73, 0x067E, 0x0664, 0x0E69,0x0FBB, 0x07B6, 0x07AC, 0x0FA1, 0x0798, 0x0F95, 0x0F8F, 0x0782,0x07F0, 0x0FFD, 0x0FE7, 0x07EA, 0x0FD3, 0x07DE, 0x07C4, 0x0FC9,0x0720, 0x0F2D, 0x0F37, 0x073A, 0x0F03, 0x070E, 0x0714, 0x0F19,0x0F6B, 0x0766, 0x077C, 0x0F71, 0x0748, 0x0F45, 0x0F5F, 0x0752 };// 第n个字节Bn求CRC12相当于// Bn 00 00 添12个0对180DH求余// Bn:xy 00 0// -----------------// |(Hi) |(Lo)// Cn: | ab | c// Bn+1 | de | 0 00// +-----+---------// B'n | fg | c 00 B'n = Bn+1^Cn_Hi 查表求得Tn的校验码C'n = i jk // C'n i jk// ----------// l jk//// Cn+1 = ((Cn&0x0F) << 8) ^ C'nCn = 0;for(n=0; n<len; n++){ab = ( Cn & 0x0FF0 ) >> 4;fg = buff[n]^ab;Cn = ((Cn&0x000F) << 8) ^ awCRC_Code[fg];}return Cn;}。
CRC校验算法分析及C语言实现
运算, 让被校验数据能为某一提前选定的生成多项式所除, 如果能除尽, 表明代码正确, 如果除不尽, 表明代 码错误, 余数则指明出错位所在位置% 因为任意一组仅由信息位组成的码, 很可能除不尽, 所以在信息位后附 加若干称为校验位的冗余位, 可以保证由信息位和冗余位组成的码组能被生成多项式整除, 如图’所示% 生成多项式的选取决定了校验位的宽度以及编码的检纠错能力, 通信系统中常用的生成 * + * 校验中, 多项式为: / * + *$ ’ , 0 + * / * + *$ ’ , * 7 . . (5) , 4 $$% ’ % " " 1 6 (5) , 4 $$% ’ ’ " ! ’ 6 … ’ … ’ " " " ’ ’ ’ &$ ’ &$ ! " " ($ ’ ($ ! ’ " " ! #" ! #
CRC校验算法及C#程序实现
CRC校验算法及C#程序实现CRC校验可以运用于传输数据过程中的验证,发送端发送有效数据时,先根据有效数据和生成多项式(比如CCITT标准的多项式是X16+X12+X5+1)计算出CRC校验码,把CRC校验码加到有效数据后面一起发送;当接收数据时,取出前面有效数据部分,用同样生成多项式计算出CRC校验码,然后取出接收数据后面CRC校验码部分,对比两个校验码是否相同。
如果相同,认为接收到的数据与发送的数据是一致的,传输正确;如果不同,认为传输数据出错。
CRC(循环冗余校验)算法主要是一个计算除法的过程。
算法有两个输入值,第一个是输入的信号,这通常是一个很长的数据,作为被除数。
第二个是一个与具体的CRC算法相关的多项式,称为生成多项式,用作除数。
基本的计算过程是,两者作模2除法(本质上是对应位做异或运算),余数就是CRC校验码的结果。
I、基本算法(人工笔算):以CRC16-CCITT为例进行说明,它的生成多项式是X16+X12+X5+1,CRC校验码为16位,生成多项式17位。
假如数据流为4字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0];数据流左移16位,相当于扩大256×256倍,再除以生成多项式0x11021,做不借位的除法运算(相当于按位异或),所得的余数就是CRC校验码。
发送时的数据流为6字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0]、CRC[1]、CRC[0];II、计算机算法1(比特型算法):1)将扩大后的数据流(6字节)高16位(BYTE[3]、BYTE[2])放入一个长度为16的寄存器;2)如果寄存器的首位为1,将寄存器左移1位(寄存器的最低位从下一个字节获得),再与生成多项式的简记式异或;否则仅将寄存器左移1位(寄存器的最低位从下一个字节获得);3)重复第2步,直到数据流(6字节)全部移入寄存器;4)寄存器中的值则为CRC校验码CRC[1]、CRC[0]。
crc校验程序-c语言
uint acc=0,i,j=0;
while(len--)
{
acc=acc^(*s++<<8);
for(i=0;i++<8;)
从机程序:
#define_PPDATAR_H
#include <reg51.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
/*握手信号宏定义*/
#define CALL 0x24//主机呼叫
#define OK 0x00//从机准备好
{
uchar i = 0;
uchar tmp;
/*发送呼叫信号CALL并接收应答信息,如果没有接收到从机准备好的信号,则重新发送呼叫帧*/
while(tmp!=OK)
{
/*发送呼叫信号CALL */
TI = 0;
SBUF = CALL;
while(!TI);
TI = 0;
/*接收从机应答*/
RI = 0;
void si()
{
unsigned int M;
a=x%10;
M=x/10;
b=M%10;
M=M/10;
c=M%10;
d=M/10;//a取出第四位,b取出第三位,c取出第二位,d取出第一位
}
//***********************显示**********************//
void display()
#define MAXLEN 64//缓冲区最大长度
uchar buf[MAXLEN];
c语言crc校验函数
c语言crc校验函数C语言中的CRC校验函数通常用于计算数据的循环冗余校验码,以便验证数据的完整性和准确性。
CRC校验算法通常用于通信协议、存储系统和数据传输中。
下面我将从多个角度介绍C语言中CRC校验函数的相关内容。
首先,CRC校验函数的实现通常需要一个预先定义的CRC多项式和初始值。
常见的CRC多项式包括CRC-8、CRC-16、CRC-32等,每种CRC多项式都有对应的生成多项式。
在实际编程中,可以通过查表或直接计算的方式来实现CRC校验函数。
其次,CRC校验函数的实现通常包括初始化CRC寄存器、按位处理数据、最终异或处理等步骤。
在C语言中,可以使用位运算和循环结构来实现这些步骤。
需要注意的是,不同的CRC多项式和初始值会影响CRC校验函数的实现细节。
另外,C语言中有许多开源的CRC校验函数库,如zlib、libcrc等,这些库提供了通用的CRC校验函数实现,可以直接在项目中引用和调用。
使用这些库可以简化CRC校验函数的实现过程,提高开发效率。
此外,对于特定的应用场景,可能需要根据实际需求定制CRC 校验函数。
这包括选择合适的CRC多项式、优化计算性能、处理数据端对齐等方面。
定制CRC校验函数需要充分理解CRC算法的原理和实现细节,并进行充分的测试验证。
总之,C语言中的CRC校验函数是一个重要且常见的功能,实现CRC校验函数需要充分理解CRC算法的原理和实现细节,选择合适的CRC多项式和初始值,并根据实际需求进行定制化的实现。
通过合理的设计和实现,可以保证数据的完整性和准确性,提高系统的稳定性和可靠性。
C语言实现CRC校验(多种方法)
}
上面的程序根据运算分析而来,很容易理解。为了节约内存空间,我们对程序作进一步的简化。分析可知,当二进制序列中上一位计算的余数第15bit位为1时,即( 上一位计算的余数 & 0x8000) != 0,计算本位时,上一位余数 * 2后可对0x11021作求余运算,然后再加上本位计算所得余数。这个很好理解,也就是说,打个比方,把它看作简单的除法,计算上一位时的余数乘以2后,如果比较大可以当被除数,就再去除除数求余。有一点和普通除法不同的是,因为多项式除法中采用不带借位的减法运算,所以0x10000也可以被0x11021除,余数并非为0x10000,而是0x1021。这个自己动手算一下就知道了。余数之和也是不带进位的加法运算,即异或。最后还强调一点,因为二进制序列是左移16位后参与运算的,所以,一直算到序列的最后一位也是可以被除的,这点大家要明白。下面给出简化后的C语言实现。
2、按位计算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) + ……
CRC算法原理及C语言实现
CRC算法原理及C语言实现CRC(Cyclic Redundancy Check)循环冗余校验算法是一种常用的错误检测算法,广泛应用于数据通信、存储等领域。
它通过对发送的数据进行多项式计算,得到一个校验值,然后将这个校验值附加到数据末尾,接收方再进行校验,通过比较接收到的校验值和重新计算的校验值来判断数据是否出现错误。
本文将介绍CRC算法的原理以及如何使用C语言实现。
一、CRC算法原理1.多项式表示CRC算法使用一个多项式来进行计算,这个多项式称为校验多项式(Generator Polynomial)。
在CRC算法中,校验多项式是一个二进制数,其中最高位为1,低位为0。
例如,CRC-32算法的校验多项式是0x04C11DB72.计算过程(1)初始化:将校验值设为一个固定的初始值,通常为全为0的二进制数。
(2)数据处理:逐位处理输入的数据,包括附加校验值的数据。
(3)除法运算:对每一位数据按位异或,然后进行除法运算,取余数。
(4)更新校验值:将余数与下一位数据进行异或运算,再将结果作为新的校验值。
(5)重复上述步骤,直到处理完所有的数据。
3.校验结果CRC算法的校验结果即为最后得到的校验值。
在进行校验时,接收方使用相同的校验多项式,对接收到的数据进行相同的操作,得到的校验值与发送方发送的校验值进行比较,如果相同,则说明数据未发生错误,否则则说明数据出现了错误。
二、C语言实现CRC算法下面是一个简单的C语言实现CRC算法的例子,以CRC-32算法为例:```c#include <stdio.h>//初始化校验值unsigned int crc32_inireturn 0xFFFFFFFF;//计算CRC值unsigned int i, j;for (i = 0; i < length; i++)crc = crc ^ data[i];for (j = 0; j < 8; j++)if ((crc & 1) != 0)crc = (crc >> 1) ^ CRC32_POLYNOMIAL;} elsecrc = crc >> 1;}}}return crc;int maiunsigned char data[] = "Hello, World!";unsigned int crc = crc32_init(;printf("CRC-32 value: %08X\n", crc ^ 0xFFFFFFFF);return 0;```以上就是CRC算法的原理及使用C语言实现的内容。
CRC校验原理及其C语言实现-机电之家网PLC技术网
CRC校验原理及其C语言实现-机电之家网PLC技术网CRC校验原理及其C语言实现在数据存储和数据通讯领域,CRC无处不在:著名的通讯协议X.25的FCS(帧检错序列)采用的是CRC. CCITT,ARJ、LHA等压缩工具软件采用的是CRC32,磁盘驱动器的读写采用了CRC16,通用的图像存储格式GIF、TIFF等也都用CRC作为检错手段。
CRC的本质是模-2除法的余数,采用的除数不同,CRC的类型也就不一样。
通常,CRC的除数用生成多项式来表示。
最常用的CRC码的生成多项式有CRC16,CRC32.以CRC16为例,16位的CRC码产生的规则是先将要发送的二进制序列数左移16位(既乘以2^16)后,再除以一个多项式,最后所得到的余数既是CRC码,如下式所示,其中K(X)表示n位的二进制序列数,G(X)为多项式,Q(X)为整数,R(X)是余数(既CRC码)。
K(X)>>16=G(x)Q(x)+R(x)求CRC码所采用模2加减运算法则,既是不带进位和借位的按位加减,这种加减运算实际上就是逻辑上的异或运算,加法和减法等价,乘法和除法运算与普通代数式的乘除法运算是一样,符合同样的规律。
生成CRC码的多项式如下,其中CRC-16和CRC-CCITT产生16位的CRC码,而CRC-32则产生的是32位的CRC码PLC资料网接收方将接收到的二进制序列数(包括信息码和CRC 码)除以多项式,如果余数为0,则说明传输中无错误发生,否则说明传输有误,关于其原理这里不再多述。
用软件计算CRC码时,接收方可以将接收到的信息码求CRC码,比较结果和接收到的CRC码是否相同。
CCITT推荐的高级数据链路控制规程HDLC的帧校验序列FCS中,使用CCITT-16即CRC16,其生成多项式为G(x)=x16+x12+x5 +1, CRC-32的生成多项式为G(x)=x32+x26+x23+x22+x16+x11+x10+x16+x8+x7+x5+x4+x 2+x+1 以上是摘录的一段介绍,是不是觉得很玄?我第一次看也是觉得很晕,后来查询了一些规约和协议的实现资料以后,才恍然大悟。
CRC校验方法用C语言实现源代码
CRC校验方法用C语言实现源代码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位,除以一个多项式,最后所得到的余数就是CRC码。
求CRC码所采用的是模2运算法则,即多项式除法中采用不带借位的减法运算,运算等同于异或运算。
这一点要仔细理解,是编程的基础。
CRC-16: (美国二进制同步系统中采用) G(X) = X16 + X15 + X2 + 1 CRC-CCITT: (欧洲CCITT推荐) G(X) = X16 + X12 + X5 + 1 CRC-32: G(X) = X32 + X26 + X23 + X22 + X16 +X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + 1 2、按位计算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 000起对0x11021求余,这一步理解应该没什么问题。
CRC校验算法原理及C语言实现(1)
while(len--)
{
//把字符串分为每个字节处理的数学理论基础:
//a xor b=a+b=a-b
//word=byte_h + byte_l,例word=0xABCD,byte_h=0xAB00,byte_l=0x00CD
//word xor b=(byte_h+byte_l)xor b=byte_h xor b xor byte_l ;//因此字符串可以按字节处理,并把上一字节的处理结果
{
unsigned short reg_crc;
unsigned short s_crcchk;
s_crcchk = 0;
reg_crc = 0xffff; //CRC预设
//CRC预设,CRC预设值一般为全或全,预设值不同,CRC结果也不同;另外,正向算法和逆向算法的CRC结果也不同
//每次从字符串里取最高位字节与CRC寄存器异或后回存到CRC寄存器,然后根据CRC寄存器最高位进行操作
{//循环处理字节中的每一位
if(reg_crc & 0x01)//低位在前,高位在后(低位----高位)
{//余式高位为
//reg_crc = (reg_crc >> 1)^0xa001;
reg_crc >>=1;
reg_crc = reg_crc^poly;
}
else
{//余式高位为(与异或保持不变)
{
unsigned long Table_CRC[256]; // CRC 表
unsigned long i;
unsigned short nAccum = 0;
BuildTable16( aPoly, Table_CRC ); //创建CRC表
c语言crc校验例程a001
C语言CRC校验例程1. 介绍CRC(Cyclic Redundancy Check)是一种广泛用于数据传输的校验方法,通过对数据进行多项式运算得到校验值,以验证数据的完整性和准确性。
在通信和存储系统中,CRC校验常用于检测数据传输过程中的错误,防止数据的损坏或篡改。
本文将介绍C语言中的CRC校验例程,以帮助读者了解和使用CRC校验算法。
2. CRC校验算法原理CRC校验算法是基于多项式运算的一种校验方法。
它通过对数据的每个字节进行位运算,并不断更新一个寄存器的值,最终得到校验值。
具体步骤如下:- 初始化寄存器为一个预设的值。
- 按照预定的运算规则,对数据的每个字节进行位运算,并更新寄存器的值。
- 对最终的寄存器值进行进一步处理,得到最终的校验值。
3. CRC校验算法实现C语言中可以通过以下方式实现CRC校验算法:1) 选择合适的CRC多项式和初始值。
不同的应用场景可能需要选择不同的CRC多项式和初始值,因此在实现CRC校验算法时,需要根据具体的需求来选择合适的参数。
2) 实现位运算函数。
使用C语言的位运算操作(如按位与、按位异或等),对数据进行逐位操作,以实现CRC校验算法的运算过程。
需要注意的是,位运算需要根据具体的CRC多项式来确定运算规则。
3) 实现CRC校验函数。
将CRC校验算法的运算过程封装成一个函数,以便在需要时调用。
该函数需要接受数据和数据长度作为输入,并返回计算得到的CRC校验值。
4. 示例代码下面是一个简单的C语言CRC校验例程,用于计算数据的CRC校验值:```c#include <stdio.h>/* CRC多项式 */#define CRC_POLYNOMIAL 0xEDBxxx/* 初始化寄存器值 */#define CRC_INITIAL 0xFFFFFFFF/* CRC校验函数 */unsigned int crc32(const unsigned char *data, int len) {unsigned int crc = CRC_INITIAL;int i, j;for (i = 0; i < len; i++) {crc = crc ^ data[i];for (j = 0; j < 8; j++) {if (crc 0x1) {crc = (crc >> 1) ^ CRC_POLYNOMIAL;} else {crc = crc >> 1;}}}return crc ^ CRC_INITIAL;}int m本人n() {unsigned char data[] = {0x01, 0x02, 0x03, 0x04, 0x05}; unsigned int crc = crc32(data, sizeof(data));printf("CRC32: 0xX\n", crc);return 0;}```5. 总结本文介绍了C语言中CRC校验例程的实现方法,通过选择合适的CRC多项式和初始值,以及使用位运算函数,实现了一个CRC校验算法的示例代码。
c语言crc校验程序查表法
c语言crc校验程序查表法
(原创版)
目录
1.CRC 校验原理
2.C 语言 CRC 校验程序实现
3.查表法在 CRC 校验中的应用
4.实例:使用查表法实现 CRC 校验
正文
一、CRC 校验原理
CRC(Cyclic Redundancy Check,循环冗余校验)是一种基于二进制多项式的数据校验技术。
它通过在数据末尾附加一些校验位,然后接收方在接收到数据后,通过相同的计算方法,对数据进行校验,以判断数据在传输过程中是否发生了改变或损坏。
CRC 校验的主要优点是能够检测出大部分数据传输错误,且计算简单,易于实现。
二、C 语言 CRC 校验程序实现
C 语言中实现 CRC 校验的主要步骤如下:
1.首先,根据需要生成一个二进制多项式。
这个多项式可以是固定的,也可以是随机生成的。
2.将待校验的数据用二进制表示,并在数据末尾添加一些校验位,使得整个数据长度可以被二进制多项式整除。
3.使用二进制多项式去除数据,得到一个余数。
这个余数就是 CRC 校验的结果。
4.在接收端,使用相同的方法计算 CRC 校验结果,然后将其与发送端得到的结果进行比较。
如果二者相同,则认为数据传输正确;如果不同,
则认为数据发生了改变或损坏。
三、查表法在 CRC 校验中的应用
查表法是一种常用的 CRC 校验算法。
它通过预先计算一组 CRC 值,并将其存储在表格中。
在需要进行 CRC 校验时,只需要查找对应的 CRC 值即可。
这种方法的优点是计算速度快,节省存储空间。
CRC校验算法的分析及C语言实现
CRC校验算法的分析及C语言实现CRC(Cyclic Redundancy Check)是一种简单但有效的校验算法,广泛用于数据通信中的错误检测。
它通过多项式除法实现,可以高效地检测数据传输中的位错误。
以下是对CRC校验算法的分析以及C语言实现。
分析:CRC校验算法基于多项式除法的原理。
它使用一个固定的生成多项式(G),将待校验的数据(信息位)和校验位合并在一起进行除法运算。
在发送端,将生成的余数校验位附加到数据后面一起传输;在接收端,再次进行除法运算,如果整个除法运算的余数为0,则表示数据传输无错误,否则表示数据有错误。
CRC校验算法的核心是生成多项式,它决定了校验能够检测的错误类型和错误个数。
常用的生成多项式有CRC-8、CRC-16和CRC-32、生成多项式的选择需要根据具体的应用场景和需求进行权衡,不同的生成多项式对应不同的CRC校验算法。
C语言实现:以下是一个简单实现CRC-16校验算法的示例代码:```c#include <stdio.h>#define CRC_POLYNOMIAL 0x8005unsigned int crc16(unsigned char* data, int length)unsigned int crc = 0;int i, j;for (i = 0; i < length; i++)crc ^= (unsigned int)data[i] << 8;for (j = 0; j < 8; j++)if (crc & 0x8000)crc = (crc << 1) ^ CRC_POLYNOMIAL;} elsecrc <<= 1;}}}return crc;int maiunsigned char data[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB}; int length = sizeof(data) / sizeof(data[0]);unsigned int checksum = crc16(data, length);printf("Checksum: 0x%04X\n", checksum);return 0;```在该示例代码中,`crc16`函数接受待校验的数据和数据长度作为输入,返回计算得到的CRC校验值。
差错控制技术(海明码和CRC)
VS
机遇
随着5G、6G等新一代通信技术的发展, 差错控制技术将迎来更多的应用场景和市 场需求。
差错控制技术在通信领域的应用前景
无线通信
差错控制技术是无线通信系统中的重要组成部分,对于保障数据 传输的可靠性和稳定性具有重要作用。
有线通信
在有线通信领域,差错控制技术同样具有广泛的应用前景,如光纤 通信、宽带接入等。
03
CRC原理及实现
CRC的原理
循环冗余校验(CRC)是一种利 用数据传输中的冗余信息进行错 误检测和纠正的差错控制技术。
CRC的基本思想是利用多项式编 码理论,通过一个生成多项式对 数据进行处理,使得数据的冗余 信息以某种规律分布在数据中, 从而在接收端通过同样的多项式 对接收数据进行校验,判断数据 是否出错。
02
海明码原理及实现
海明码的原理
海明码是一种线性纠错码,通过在数据位之间 添加冗余校验位,实现错误检测和纠正。
海明码基于奇偶校验原理,通过将数据位和校 验位进行奇偶校验,检测出错误的位置。
海明码可以分为奇偶校验码和循环冗余校验码 (CRC),其中奇偶校验码又可以分为水平奇 偶校验、法进 行运算,将待校验的数据左移若 干位后与生成多项式进行模2除法 运算,得到余数即为CRC校验码。
CRC的编码过程
01
02
03
发送端将数据左移k位( k为生成多项式的位数) ,相当于在数据后面添
加k个0。
将移位后的数据除以生 成多项式,得到余数即
为CRC校验码。
将余数附加在原始数据 后面,一起发送到接收
智能化
01
利用人工智能和机器学习技术,实现差错控制系统的自适应和
自优化,提高差错控制性能。
CRC校验方法用C语言实现源代码
CRC校验方法用C语言实现源代码以下是一个使用C语言实现CRC校验方法的示例代码:```c#include <stdio.h>#include <stdint.h>#define POLYNOMIAL 0x1021 // CRC-CCITT standard polynomial #define INITIAL_VALUE 0xFFFF // Initial value for CRC registeruint16_t crc16(uint8_t *data, uint32_t length)uint16_t crc = INITIAL_VALUE;for (uint32_t i = 0; i < length; i++)crc ^= (uint16_t) data[i] << 8; // XOR with next bytefor (uint8_t j = 0; j < 8; j++)if (crc & 0x8000) { // Check if MSB is setcrc = (crc << 1) ^ POLYNOMIAL; // Left-shift and XOR polynomial} elsecrc <<= 1; // Left-shift without XOR}}}return crc;int maiuint8_t data[] = {0x01, 0x02, 0x03, 0x04}; // Example datauint32_t dataLength = sizeof(data) / sizeof(data[0]);uint16_t crc = crc16(data, dataLength);printf("CRC: %04X\n", crc);return 0;```这段代码实现了一个使用CRC-CCITT标准多项式(POLYNOMIAL)进行CRC校验的函数`crc16`。
海明码和CRC校验的C语言实现
*/
void InputBinary(char *data)
{
for(int i=0;i<N;i++)//循环输入待编码数据,遇到非'1'非'0'输入结束输入
{
data[i]=getche();
if(data[i]!='0'&&data[i]!='1')
{
data[i]='\0';
for(k=0;k<N;k++)//循环输入待编码数据并记录数据长度,遇到非'1'非'0'输入结束输入
{
data[k]=getche();
if(data[k]!='0'&&data[k]!='1')
{
break;
}
}
printf("\n__________________________________________________________\n");
for(int j=1;j<r+k+1;j++)//组合输出数据和校验码
{
if(j==(int)pow(2,cnum))
{
printf("%c",c[cnum]);
cnum++;
}
else
{
printf("%c",data[dnum]);
dnum++;
}
}
getch();
}
/*
*@func:计算校验码
C# 编写的简单易懂的串口通讯代码带CRC校验 带详细的注释
C# 编写的简单易懂的串口通讯代码带CRC校验带详细的注释Class_SerialPort 类代码using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO.Ports;namespace Modbus_Tcp_IP{public class HexCode{/// <summary>/// 从汉字转换到16进制/// </summary>/// <param name="s"></param>/// <param name="charset">编码,如"utf-8","gb2312"</param>/// <param name="fenge">是否每字符用逗号分隔</param>/// <returns></returns>public static string ToHex(string s, string charset, bool fenge){if ((s.Length % 2) != 0){s += " ";//空格//throw new ArgumentException("s is not valid chinese string!");}System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);byte[] bytes = chs.GetBytes(s);string str = "";for (int i = 0; i < bytes.Length; i++){str += string.Format("{0:X}", bytes[i]);if (fenge && (i != bytes.Length - 1)){str += string.Format("{0}", ",");}}return str.ToLower();}/// <summary>/// 从16进制转换成汉字/// </summary>/// <param name="hex"></param>/// <param name="charset">编码,如"utf-8","gb2312"</param>/// <returns></returns>public static string UnHex(string hex, string charset){if (hex == null)throw new ArgumentNullException("hex");hex = hex.Replace(",", "");hex = hex.Replace("\n", "");hex = hex.Replace("\\", "");hex = hex.Replace(" ", "");if (hex.Length % 2 != 0){hex += "20";//空格//throw new ArgumentException("hex is not a valid number!", "hex");}// 需要将hex 转换成byte 数组。
CRC校验方法用C语言实现源代码
CRC校验方法用C语言实现源代码下面是一个使用C语言实现CRC校验方法的源代码示例:```c#include <stdio.h>unsigned long crc_table[256];void generate_crc_tablunsigned long crc;int i, j;for (i = 0; i < 256; i++)crc = i;for (j = 0; j < 8; j++)if (crc & 1)crc = (crc >> 1) ^ POLYNOMIAL;elsecrc >>= 1;}crc_table[i] = crc;}unsigned long calculate_crc(unsigned char *data, intdata_length)unsigned long crc = 0xFFFFFFFF;int i;for (i = 0; i < data_length; i++)crc = (crc >> 8) ^ crc_table[(crc ^ data[i]) & 0xFF];}return crc ^ 0xFFFFFFFF;int maiunsigned char data[] = "hello crc";int data_length = sizeof(data) - 1; // excluding null terminatorgenerate_crc_table(;unsigned long crc = calculate_crc(data, data_length);printf("CRC: 0x%08lX\n", crc);return 0;```这个示例代码实现了一个通用的CRC校验方法,通过生成CRC表并使用循环计算CRC值。
C语言:CRC校验
C语言:CRC校验一、CRC码CRC:Cylic Reduancy check译作汉语就是循环冗余校验码。
二、XORXOR:逻辑运算符异或,不知道用符号怎么写,总之其运算法则是,不同为1,相同为0。
三、用XOR代替算术运算上除法的两个例子。
1、10110010000/11001第一次异或(相除),得到商为1,余数为1111,加入下一位0,进行第二次异或,得到商为1,余数为111,加入下一位1,余数为1111,四位与除数5位不能够异或计算,所以此处商为0,加入下一位0,进行第三次异或,得到商为1,余数为111,同理第5位商为0,余数继续加入被除数的下一位0,进行第四次异或,得到商为1,余数为101,加入后一位被除数的0,得到商为0,最终余数为1010,而最终商为1101010。
计算流程如下图所示:如若让被除数10110010000加上余数1010则为10110011010,再除以(异或)11001,则得到余数为0000(此处不再具体计算).2、1111000/1001经过三次异或(相除)得到商为1110,余数为110,具体例程如下,同样,让该例的被除数1111000加上余数110后为1111110除以(异或)除数100则得到余数为000.四、CRC校验原理由以上两个例子可以看出,通信过程中加入想要传送的数据是“被除数”,加上余数后再传送。
而接收一方接收完整数据后,除以除数,如果余数为0,则说明传送的数据正确,如果不为0则说明传送的数据有误。
因为对于一个确定的“除数”,则就会有唯一的余数与之对应。
这个过程其实就是一个CRC的校验过程。
不过名称改一下不能叫做被除数除数什么的。
可以规定上述的除数叫做生成多项式或生成项,用g(x)表示。
而余数就叫做CRC校验码。
由以上知道,对于不同的生成项,则就会有唯一的CRC校验码与之对应。
而对于要传送的数据也可以用一个系数仅为0和1取值的多项式一一对应。
例如代码1010111对应的多项式为x^6+x^4+x^2+x+1.而多项式x^5+x^3+x^2+x+1对应的代码是101111.实际上,上述的被除数并不是真正的要传送的数据,真正要传送的数据是一个多项式左移CRC校验码位数后的代码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
海明码和CRC校验的C语言实现1.海明码//code by zxf 2010.4.10#include <stdio.h>#include <conio.h>#include <math.h>//N代表待编码数据的上限位数#define N 100int HmLength(int k);//计算海明码校验位位数void InCode(char *data,char *c,int k,int r);//计算海明码每个校验位的数值void main(){int k=0,r=0,dnum=0,cnum=0;char data[N];char c[N];clrscr();printf("Now please input the data you want to Incode:");for(k=0;k<N;k++)//循环输入待编码数据并记录数据长度,遇到非'1'非'0'输入结束输入{data[k]=getche();if(data[k]!='0'&&data[k]!='1'){break;}}printf("\n__________________________________________________________\n");r=HmLength(k);//求取校验位数printf("k=%d r=%d The length of Hamming code=%d\n",k,r,r+k);//输出海明码相关位数信息InCode(data,c,k,r);//计算海明码printf("The Hamming code is:");for(int j=1;j<r+k+1;j++)//组合输出数据和校验码{if(j==(int)pow(2,cnum)){printf("%c",c[cnum]);cnum++;}else{printf("%c",data[dnum]);dnum++;}}getch();}/**@func:计算校验码*@param:data 待编码数据,c 校验码,k 数据长度,r 校验码位数*code by zxf*/void InCode(char *data,char *c,int k,int r){for(int i=0;i<r;i++)//循环计算第i位校验位{int sum=0,dnum=0,cnum=0;for(int j=1;j<r+k+1;j++)//计算海明码和矩阵第r-i列的乘积{if(j==(int)pow(2,cnum))//去掉矩阵的全零行{cnum++;//记录校验码循环位数}else{int x=0,y=0;x=pow(2,i);y=j%(x*2);x=y/x;//通过取余取商计算获取矩阵第r-i列第j行元素的值sum+=data[dnum]*x;//累加乘积dnum++;//记录数据的循环位数}}c[i]=sum%2==0?'0':'1';//通过结果的奇偶设置校验位的值}}/**@func:计算校验码的位数*@param: k 数据长度*@return: 校验码位数*code by zxf*/int HmLength(int k){int r=0,flag=1;while (flag!=0)//循环到2^r-1>=r+K时即得到校验码的位数{int temp=0;temp=pow(2,r);temp=temp-1;flag=(temp-r-k<0);r++;}return r-1;}程序演示:计算1100计算1000001计算10101010101010101010101010101010101010CRC校验//code by zxf 2010.4.10#include <stdio.h>#include <conio.h>#include <string.h>//N代表待编码数据的上限位数#define N 100void InputBinary(char *data);//输入二进制int DelZero(char *data);//去掉二进制字符串前面的零位int Div(char *data,char *div);//进行一次模2除法void main(){char datacpy[N];char data[N];char div[N];char res[N];int reslen=0;clrscr();printf("now please input the data:");InputBinary(data);//输入Mprintf("\nnow please input the div:");InputBinary(div);//输入除数DelZero(data);DelZero(div);//取得有效的M和除数strcpy(datacpy,data);//备份Mprintf("\nThe effective data is:%s",data);printf("\nThe effective div is:%s",div);for(int i=0;i<strlen(div)-1;i++)//得到2^nM{data[strlen(data)]='0';}data[strlen(data)]='\0';res[reslen]='0';while (Div(data,div))//进行模2除法{int i=DelZero(data);res[reslen]='1';//记录商reslen++;if(strlen(data)>=strlen(div))//记录零商{for(int j=0;j<i;j++){res[reslen]='0';reslen++;}}}res[reslen]='\0';while(strlen(data)<strlen(div)-1)//若FCS位数不足n则进行补零操作{for(int i=strlen(data);i>0;i--){data[i]=data[i-1];}data[0]='0';}//输出结果printf("\n_______________________________________________________________");printf("\nThe div result is:%s",res);printf("\nThe FCS is:%s",data);printf("\nThe data wish FCS is:%s%s",datacpy,data);getch();}/**@func:二进制输入*@param:data 用于存储输入数据的字符串*code by zxf*/void InputBinary(char *data){for(int i=0;i<N;i++)//循环输入待编码数据,遇到非'1'非'0'输入结束输入{data[i]=getche();if(data[i]!='0'&&data[i]!='1'){data[i]='\0';break;}}}/**@func:删除二进制串的起始'0'*@param:data 待处理字符串*@return:返回删除零的个数-1*code by zxf*/int DelZero(char *data){int res=-1;while(data[0]=='0')//如果data第一位为'0'继续前移字符串{for(int i=0;i<strlen(data);i++)//前移字符串{data[i]=data[i+1];}res++;}return res;}/**@func:进行一次模2除法*@param:data 被除数, div 除数*@return:返回0:被除数小于除数,返回1:成功进行了一次模2除法*code by zxf*/int Div(char *data,char *div){int res=0;if(strlen(data)<strlen(div)) ;//被除数小于除数不操作else{for(int i=0;i<strlen(div);i++)//按位进行模2除法{data[i]=data[i]==div[i]?'0':'1';}res=1;}return res;}程序演示:计算101001计算1101011011。