crc循环冗余校验码c语言,CRC循环冗余校验码的生成
众所周知,不可能有永远都不会出错的人,同样也不可能有永远不出错的计算机,永远不出错的数据。
人有知错能改的觉悟,计算机也有,不过计算机没有人类聪明,只能通过一个特定的方法进行自我改正,这就是校验码存在的必要了。
一般用得比较多的校验码有奇偶校验码,CRC循环冗余校验码,海明校验码等。
这里只介绍用的最多的CRC循环冗余校验码。
何为校验码
校验码是通过一种计算方法,发出端在原始数据的尾部添加若干数据;然后接收端通过计算得出数据有无错误,并且能把错误的数据还原成正确的数据。
例如,原始数据为1010,我们通过在其尾部添加若干数据,比如101,则数据变成了1010101,将这个新的数据发送出去;假如在发送过程中出现错误,数据变成了1110101,则接收端能根据1110101还原成原始正确的数据1010。
CRC循环冗余校验码的特点
CRC码是基于模2运算建立编码规律的校验码(模2运算可以简单的理解为异或运算)。
编码方法:
1.将原始数据用一个多项式M(x) = A*X^(n-1)+B*X^(n-2)+…+N*X^(1)+P*X^(0)
比如说原始数据是1010,则表示为M(x) = 1*X^(3)+0*X^(2)+1*X^(1)+0*X^(0)
2.将原始数据左移k位,得到M(X)*X^k,形成了n+k位信息。
上面的1010,左移3位,得到1010 000
3.用多项式M(X)*X^k 除以(或者说异或)一个特定的生成多项式G(X),所得余数则为需要拼接到原始数据尾部的CRC校验码。
例:
已知原始数据为1100,生成多项式G(X)=1011,则求算CRC码的过程如下:
已知 :M(X) = 1100 = X^3+X^2 (n=4)
由 G(X) = 1011 = X^3+X^1+1
得 k+1 = n = 4
得 k=3,需要左移3位
故得 M(X)*X^3 = 1100 000
(M(X)*X^3) / G(X)计算过程:
1100 000 M(X)*X^3
1011 G(X)
--------------
111 0 余数,高位0省去;然后余数左移1位,继续异或G(X)
101 1 G(X)
---------------
10 10 左移1位,继续异或G(X)
10 11
----------------
10 由于k=3,而算到这里我们已经对余数移位2次,还需1次
则最后算出来的结果是010,则原始数据变成了1100 010,最后三位是CRC码。
很容易发现,如果我们需要算k位码,则G(X)的位数应该是K+1.
由于最后的数据变成了7位,而有效数据还是4位,故上述的1100 010码又叫做(7,4)码,对应的还有(7,3)码,(7,6)码等。
CRC码的译码规则和纠错方法
还是刚刚的例子,我们用最后得出的数据除以G(X),发现其余数为0,这个就是正确的数据。
我们尝试改动其中一位,比如说第2位,得到:1000 010,我们用这个数除以G(X),发现余数为111,余数不为0,则说明数据有错了!
下面给出每个位出错对应的余数:
序号
N1 N2 N3 N4 N5 N6 N7
余数
出错位
正确
1 1 0 0 0 1 0
000
无
错误
1 1 0 0 0 1 1
001
7
错误
1 1 0 0 0 0 0
010
6
错误
1 1 0 0 1 1 0
100
5
错误
1 1 0 1 0 1 0
011
4
错误
1 1 1 0 0 1 0
110
3
错误
1 0 0 0 0 1 0
111
2
错误
0 1 0 0 0 1 0
101
1
假如我们现在收到一个错误的信息是1000 010,通过计算可以得出余数是111,但是如何得知是第几位出错了?
我们试着对余数111补0后继续除下去,发现下一次的余数变成了101,继续下去,又变成了001,以后依次出现为010,100,011。。。反复循环,这就是“循环码”名字的由来。
这样,假如N2出现错误,则出现了不为0的余数后,一方面对余数补0继续模2除,另一方面将被检测的校验码字循环左移,当余数为101(即数据的首位为0)时,通过异或门可以将其纠正后在下一次移位时送回N2。这样当移满一个循环后,就得到一个纠正后的数据了。
最后给出几个标准
在上面的计算中可以发现,G(X)的作用非常重要,生成CRC码和译码都需要它。值得指出的是,并不是随便一个(K+1)位数据都可以作为生成多项式,它要满足的条件:
1.任何一位出错,都不能使余数为0,这是非常显然的;
2.不同位发生错误后,余数不能相同;
3.对余数继续模2除,应使余数循环。
为了方便起见,也为了标准化工作,现在一般用的生成多项式有以下几个:
CRC-16 = X16 + X15 + X2 + X0 美国二进制同步系统中采用
CRC-CCITT = X16 + X12 + X5 + X0 由欧洲CCITT 推荐
CRC-32 = X32 + X26 + X23 + X22 + X16 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + X0
下面贴出生成CRC码的代码
#include #include
using namespacestd;#define CRC_16 0x18005
//CRC-16 = X16 + X15 + X2 + X0
#define CRC_CCITT 0x11021
//CRC-CCITT = X16 + X12 + X5 + X0
#define CRC_32 0x104C11DB7
//CRC-32 = X32 + X26 + X23 + X22 + X16 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + X0
#define CHECK_CODE 0x8000
//check_code = x15,判断被除数位数>=16//check_code是为了每次做异或运算时保证位数是足够的
unsignedlong table[256];void build_16(unsigned longpoly)
{
unsignedlongx;
unsignedlongt;/*这里是将原始数据直接写入到t中
for (unsigned long i=0; i<256; i++)
{
x = i << 8;
t = 0;
for (unsigned long j = 0; j < 8; j++)
{
if ( (x ^ t) & CHECK_CODE)
t = (t << 1) ^ poly;
else
t <<= 1;
x <<= 1;
}
table[i] = ( unsigned long ) t;
}*/
//下面的是把余数和原始数据分开的写法//原始数据只有8位
for (int i=0; i<256; i++)
{
x= i<<8;//只移8位是为了位数对齐,因为下面的运算都是低位对齐的
for (int j=0; j<8; j++)
{if (x&CHECK_CODE)
{
x<<= 1;
x= x^poly;
}else x <<= 1;
}
table[i]= (i<<16)+x;
}
}void build_32(unsigned longpoly)
{
unsignedlongx;for (unsigned long i=0; i<256; i++)
{
x= i<<24;for (unsigned long j=0; j<8; j++)
{if (x & 0x80000000) //判断位数是否足够,32位
{
x<<= 1;
x= x^poly;
}else x <<= 1;
}
table[i]= (i<<32)+x;
}
}intmain()
{
build_16(CRC_16);
build_16(CRC_CCITT);
build_32(CRC_32);for (int i=0; i<256; i++)
{if (i % 10 == 0)
cout<
printf("%lx", table[i]);
}return 0;
}
crc循环冗余校验码c语言,CRC循环冗余校验码的生成相关推荐
- 易语言局域网 php 控制,易语言控制端源码,易语言被控制源码,易语言局域网远程控制源码...
下面我们对易语言控制端源码,易语言被控制源码,易语言局域网远程控制源码文件阐述相关使用资料和易语言控制端源码,易语言被控制源码,易语言局域网远程控制源码文件的更新信息. 易语言控制端源码,易语言被控制 ...
- c语言字符码,C语言字符转ASII码
如何字符转ASII码 什么是ASII码? ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符.标准ASCII 码也叫基础ASCII码,使用7 位二进制数来表示所有的 ...
- php加解密易语言源码,易语言PHP加密源码
资源介绍: 例程程序置入汇编代码,调用API函数实现易语言与PHP通讯加密协议. session_start(); ini_set("display_errors", 0); $M ...
- dnf吸怪源码c语言,发DNF源码了
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 .版本 2 .支持库 spec .支持库 EThread .支持库 eAPI .局部变量 计次, 整数型 .局部变量 过滤类型, 整数型 .局部变量 过滤 ...
- C语言写的小游戏源码,c语言小游戏源码(华容道)
[实例简介] [实例截图]见截图 [核心代码] #include #include #include #include int c=0,a[8][8]= {0},n=0,x,y,b[8][8]= {0 ...
- c调用易语言串口,易语言串口API源码
易语言串口API源码系统结构:ReadCommPure,BuildCommDCB,CreateFilea,关闭句柄a,SetCommState,ReadFileA,GetCommState,Write ...
- 易语言 普通填表 html5,易语言网页填表源码
易语言网页填表源码系统结构:passport_tianya,passport_xinlang,passport_baidu,Automatic_modification,Insert_text,Loa ...
- 易语言启动局域网计算机程序,易语言局域网计算机监控源码
易语言局域网计算机监控源码系统结构:取计算机列表,弹出提示窗,上下线, ======窗口程序集1 || ||------__启动窗口_创建完毕 || ||------取计算机列表 || ||----- ...
- 易语言html截图,易语言窗口截图源码
易语言窗口截图源码系统结构:子程序1,PaintRect,SetTimer,GetCursorPos,WindowFromPoint,KillTimer,GetWindowRect,CreateDC, ...
- 易语言服务器php,易语言PHP服务器源码
易语言PHP服务器源码系统结构:监听服务,编码转换程序,进制转换,取页面地址,取域名,取端口,取指定内容中间,取文本之间,取文本之后,ChrW,十到十六,到十六进制文本,去除首部零,URL编码_UTF ...
最新文章
- 关于在phpStudy环境下,windows cmd中 php不是内部命令问题
- Mysql实现非程序控制读写分离
- 【Java基础】面向对象特性
- 冬奥会测试赛,助理裁判竟然是个AI!
- php学历低,学历低学起php来难不难
- socket 中 SOCK_STREAM 和 SOCK_DGRAM的区别?
- Matlab神经网络十讲(7): Self-Organizing and LVQ Networks
- esp8266 防掉线方法_esp8266 smartconfig-智能配网分析和使用及注意事项
- 根据数据集获取概率密度图像和概率分布图像
- 换工作了,开始用金蝶的BOS了,好多东西都要学啊!
- HDU 4548 美素数(打表)
- 任天堂的好日子還會繼續嗎﹖
- pythonmain是什么_Python - __name__=='__main__'是干啥的,以及python -m与python的区别
- 超级浏览器对跨境亚马逊防关联有用吗?
- MSN 通信协议学习笔记(转)
- 永中word页码怎么从第二页开始_用Word自动生成目录
- maven项目配置(图书管理系统v2配置)
- D语言(dlang)编写单片机(cortex-m系列)应用需要用到的技巧
- PHP判断当前的设备是手机(Mobile)还是电脑(PC)
- 实际场景架构图实例及详细说明