ccrc校验算法
‘壹’ 谁内帮我解释一下CRC校验c语言实现的原理,原理好像是把2进制每位分别提取出来与或,但程序不懂啥意思
这里用的多项式为:X16 + X12 + X5 + X0 = 2^0+2^5+2^12+2^16=1 0001 0000 0010 0001=0x11021,因最高位一定为“1”,故略去计算只采用0x1021即可
X5 代表 Bit5,X12 代表 Bit12,1 自然是代表 Bit0,X16 比较特别,是指移位寄存器移出的数据。可以这样理解,与数据位做XOR运算的是上次 CRC值的 Bit15。
你这个实现里的for循环内容,可以理解成移位前 crc 的 Bit15 与数据对应的 Bit(*ptr&i)做 XOR运算,根据此结果来决定是否执行 crc^=0x1021。只要明白两次异或运算与原值相同,就不难理解这个程序。
if((crc&0x8000)!=0) {crc*=2; crc^=0x1021;} /* 余式CRC 乘以2 再求CRC */
if((*ptr&i)!=0) crc^=0x1021; /* 再加上本位的CRC */
‘贰’ 高分求计算CRC校验码的C语言程序
你就是想要CRC8-CCITT的代码,这个到处都是。
http://www.rajivchakravorty.com/source-code/uncertainty/multimedia-sim/html/crc8_8c-source.html
我一直有CRC16,没试过这个,但应该差不多。
参考文献:http://blog.sina.com.cn/s/blog_5e330a280100fcp9.html
‘叁’ C语言中CRC循环校验的一个程序
while(len--!=0)
这句的len的值循环一次就减少1,先执行len!=0,再执行len--。
当len为0时退出循环。
for(i=0x80;
i!=0;
i/=2)
0x80是十六进制数,也即128
当i!=0时,执行循环体,
然后i=i/2,即i值减半。
‘肆’ 用C语言实现CRC编码程序
#include <stdio.h>
#include <string.h>
#include "stdlib.h"
unsigned int char2int(char *str)
{
unsigned int count=0, ret=0;
for(count = 0; count<strlen(str);count++)
{
ret = ret<<1;
if('0' != str[count])
{ ret+=1;}
}
return ret;
}
unsigned int getR(char *str)
{
unsigned int c =0 ;
int ret = strlen(str)-1;
for(c=0;c < strlen(str);c++)
{if(str[c] != '0')<br/> {return ret-c;}
}
}
int getRi(unsigned int num)
{
int c =0;
for(;num != 0; c++)
{num = num>>1;}
return c;
}
void CRC(char *scode, char *p, char*g )
{
unsigned int iP = char2int(p);
unsigned int iG = char2int(g);
unsigned int r= getR(g);
unsigned int code = iP << r;
unsigned int yx = code;
for(;getRi(yx) >= getRi(iG);)
{ yx = yx ^ (iG<<(getRi(yx) - getRi(iG)));}
code += yx;
itoa(code,scode,2);
}
void main() //定义主函数
{
char data[8]="" , bds[8]="",code[16]="";
printf("数据:");
scanf("%s", data);
printf("表达式:");
scanf("%s", bds);
CRC(code,data,bds);
printf("编码:%s",code);
}
‘伍’ 关于CRC效验
为保证传输过程的正确性,需要对通信过程进行差错控制。差错控制最常用的方法是自动请求重发方式(ARQ)、向前纠错方式(FEC)和混合纠错(HEC)。在传输过程误码率比较低时,用FEC方式比较理想。在传输过程误码率较高时,采用FEC容易出现“乱纠”现象。HEC方式则是ARQ和FEC的结合。在许多数字通信中,广泛采用ARQ方式,此时的差错控制只需要检错功能。实现检错功能的差错控制方法很多,传统的有:奇偶校验、校验和检测、重复码校验、恒比码校验、行列冗余码校验等,这些方法都是增加数据的冗余量,将校验码和数据一起发送到接受端。接受端对接受到的数据进行相同校验,再将得到的校验码和接受到的校验码比较,如果二者一致则认为传输正确。但这些方法都有各自的缺点,误判的概率比较高。 循环冗余校验CRC(Cyclic Rendancy Check)是由分组线性码的分支而来,其主要应用是二元码组。编码简单且误判概率很低,在通信系统中得到了广泛的应用。下面重点介绍了CRC校验的原理及其算法实现。 CRC校验可以100%地检测出所有奇数个随机错误和长度小于等于k(k为g(x)的阶数)的突发错误。所以CRC的生成多项式的阶数越高,那么误判的概率就越小。 CRC代码的一些基本概念和运算: CRC多项式: 例: 代码:1010111 对应的多项式为:X6+X4+X2+X+1 多项式X5+X3+X2+X1+1对应的代码为101111 CRC生成多项式: 首位和最后一位必须是1。CRC生成多项式是给定的,在传输过程中不变,即发送和接收端生成码相同。 一些常用的校验码为: CRC8=X8+X5+X4+1 CRC-CCITT=X16+X12+X5+1 CRC16=X16+X15+X5+1 CRC12=X12+X11+X3+X2+1 CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1 CRC的运算本质是异或运算(模2除法) 例:原信息码为1011001 生成码为11001 校验码计算过程 ① 将信息码左移4位(生成码长-1);得到10110010000 ② 异或运算 10110010000 11001 01111010000(前面的数进行异或运算,后面的直接抄下来) 11001 0011110000(和生成码异或运算的必须从1开始) 11001 00111000 11001 001010 这样得到的结果为1010,即为所需要的校验码,添加到信息码后,得到发送的代码为: 10110011010 我把上面的手算过程用c#写了一段程序,如下: using System; namespace mainClass { public class mainProgress { public static void Main() { byte[] msg={1,0,1,1,0,0,1};//信息码 byte[] gmsg=new byte[msg.Length+4]; crc c = new crc(); gmsg=c.code(msg); Console.Write("编码后字符串为:"); for (int i = 0; i < gmsg.Length; i++) { Console.Write("{0}", gmsg[i].ToString()); } Console.Write("\n"); byte[] gmsg1={ 1, 0, 1, 1, 0, 1, 1 };//接收到的代码 bool r = c.det(gmsg1); if (r) { Console.WriteLine("传
‘陆’ CRC的C语言的程序
按位计算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求余,这一步理解应该没什么问题。如果该分序列为0,无需计算。
<3>对其余的二进制序列求余与上面两步相同。
<4>计算到最后一位时即为整个二进制序列的余数,即为CRC校验码。
该计算方法相当于对每一位计算,运算过程很容易理解,所占内存少,缺点是一位一位计算比较耗时。
下面给出C语言实现方法:
代码如下:
unsigned char test[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned char len = 16;
void main( void )
{
unsigned long temp = 0;
unsigned int crc;
unsigned char i;
unsigned char *ptr = test;
while( len-- ) {
for(i = 0x80; i != 0; i = i >> 1) {
temp = temp * 2;
if((temp & 0x10000) != 0)
temp = temp ^ 0x11021;
if((*ptr & i) != 0)
temp = temp ^ (0x10000 ^ 0x11021);
}
ptr++;
}
crc = temp;
printf("0x%x ",crc);
}
‘柒’ CRC校验代码 c++ java都可以
不会,建议还是自己做吧。
‘捌’ c语言 CRC的检验方式 我想问一下。这下面的C语言返回的CRC的值是什么。他有他的公式是怎么样的
CRC又称循环冗余校验,CRC返回的值其实是校验位,校验位分高位和低位。
实际应用时,发送装置计算出CRC值并随数据一同发送给接收装置,接收装置对收到的数据重新计算CRC并与收到的CRC相比较,若两个CRC值不同,则说明数据通讯出现错误。
‘玖’ modbus中如何计算CRC效验(人工计算)
在CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算。
CRC计算方法是:
1、 加载一值为0XFFFF的16位寄存器,此寄存器为CRC寄存器。
2、 把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的相异或,异或的结果仍存放于该CRC寄存器中。
3、 把CRC寄存器的内容右移一位,用0填补最高位,并检测移出位是0还是1。
4、 如果移出位为零,则重复第三步(再次右移一位);如果移出位为1,CRC寄存器与0XA001进行异或。
(9)ccrc校验算法扩展阅读:
计算步骤为:
(1).预置 16 位寄存器为十六进制 FFFF(即全为 1) ,称此寄存器为 CRC 寄存器;
(2).把第一个 8 位数据与 16 位 CRC 寄存器的低位相异或,把结果放于 CRC 寄
存器;
(3).检测相异或后的CRC寄存器的最低位,若最低位为1:CRC寄存器先右移1位,再与多项式A001H进行异或;若为0,则CRC寄存器右移1位,无需与多项式进行异或。
(4).重复步骤 3 ,直到右移 8 次,这样整个 8 位数据全部进行了处理;
(5).重复步骤 2 到步骤4,进行下一个 8 位数据的处理;
(6).最后得到的 CRC 寄存器即为 CRC 码。
‘拾’ crc16校验的c语言程序
unsigned short crc_dsp(unsigned short reg, unsigned char data_crc)
//reg为crc寄存器, data_crc为将要处理的8bit数据流
{
unsigned short msb; //crc寄存器将移出的最高1bit
unsigned short data;
unsigned short gx = 0x8005, i = 0; //i为左移次数, gx为生成多项式
data = (unsigned short)data_crc;
data = data << 8;
reg = reg ^ data;
do
{
msb = reg & 0x8000;
reg = reg << 1;
if(msb == 0x8000)
{
reg = reg ^ gx;
}
i++;
}
while(i < 8);
return (reg);
}