博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
循环冗余校验(CRC)【C语言 位运算】
阅读量:5112 次
发布时间:2019-06-13

本文共 2497 字,大约阅读时间需要 8 分钟。

 

【应用场景:数据链路层差错检验】     

送数据M,有k位;

除数P(对应一个生成多项式),有n位;

M右移n-1位的M';

计算M'/P的余数R(帧校验序列FCS);

发送帧:M’+FCS

 

(异或)

第一步:要在数据位(被除数)后边补 0 , 0 的个数比除数(生成多项式)少一位。

第二步:做除法(异或操作),从被除数的头五位减去五位的除数。除数的每一位都与被除数的对应位在不涉及上一位的情况下独立进行减法(实际进行的是模 2 加)。在本例中,除数 11001 与被除数的前五位 10110 进行的是模 2 加,得到 1111 (余数 1 前面的 0 被省略)。在被除数中下一个没有使用过的比特接着被抄录下来,使得余数的位数和除数的位数相同。如果位数不够,在商位补 0 (这与一般除法相同),因此,下一步就是 11110^11001 ,结果是 111 ,依次类推。在二进制除法中,除数总是以 1 开头的,然后从上一次的被除数 / 余数中与除数位数相同的部分中减去除数,并且只能从最左位是 1 的被除数 / 余数中减去除数。每当被除数 / 余数的最左位是 0 时,就在该步骤中把 0 丢弃,再把被除数中的下一个未使用比特抄录下来填充余数,同时对应的商数位补一个零,并按上述方法进行二进制除法运算,一直重复这个过程直到被除数中所有比特都被使用过。

余数 100 只有 3 位,而余数应为 4 位(比除数少一位),因此,取校验码时应在前面填一个 0 ,故其 CRC 校验码应为 0100 ,于是可求出该信息码的循环冗余码为 101100110100 。

为了判断传输的正确性,在接收端要有一个 CRC 校验器。它的功能和发生器一样,当收到 CRC 冗余校验码后,做同样的模 2 除法(注意,这里采用的生成多项式一定要与发送端相同)。如果余数是全 0 ,则说明传输正确;否则,传输错误,应重传。

【itoa函数可以将整型数字转为二进制字符串】

1 #include 
2 #include
3 #include
4 char res[33]; 5 unsigned int data,g,a[33]={
0, 6 0x00000001,0x00000002,0x00000004,0x00000008,0x00000010,0x00000020,0x00000040,0x00000080, 7 0x00000100,0x00000200,0x00000400,0x00000800,0x00001000,0x00002000,0x00004000,0x00008000, 8 0x00010000,0x00020000,0x00040000,0x00080000,0x00100000,0x00200000,0x00400000,0x00800000, 9 0x01000000,0x02000000,0x04000000,0x08000000,0x10000000,0x20000000,0x40000000,0x8000000010 };11 unsigned int str_int(unsigned int *d)12 {13 unsigned int i=0,t=0;14 char str[40];15 scanf("%s",str);16 while (str[i]!='\0'){17 t<<=1;18 t|=str[i]-48;19 i++;20 }21 *d=t;22 return i;23 }24 unsigned int GetData(unsigned int i){ return data&a[32-i+1]?1:0;}25 int main()26 {27 unsigned int l1,l2,l3,r,i,cas;28 printf("预处理多少条传送数据?\n");29 scanf("%d",&cas);30 while (cas--){31 //读取待传送数据k位32 printf("输入待传送数据M(不高于32位):");33 l1=str_int(&data);34 //读取除数n位35 printf("输入除数p(不高于%d位):",32-l1+1);36 l2=str_int(&g);37 //将待传送数据右移n-1位38 data<<=(l2-1);39 l1+=(l2-1);40 //模2除求余数41 r=0;i=32-l1+1;42 while (i<=32){43 r<<=1;44 r|=GetData(i);45 if(r>=a[l2]) r^=g;46 i++;47 }48 //输出结果49 data>>=(l2-1);50 printf("发送帧:%s",itoa(data,res,2));51 itoa(r,res,2);52 l3=strlen(res);53 for(i=l3;i

 

 

 

 

 

 

转载于:https://www.cnblogs.com/CheeseZH/archive/2012/06/03/2532532.html

你可能感兴趣的文章
Jquery插件汇集:
查看>>
Linux 启动、关闭、重启网络服务的两种方式
查看>>
List<T>列表通用过滤模块设计
查看>>
【模板】最小生成树
查看>>
设计模式之结构型模式
查看>>
修改navigationitem的title颜色字体阴影等属性
查看>>
前端开发中提到的“脚手架”到底指什么,CLI?gulp 和 gulp-cli有什么区别
查看>>
iis7规范URL及利用web.config进行重定向
查看>>
【Linux】入门篇 环境搭建
查看>>
poj2569
查看>>
使用mmap在内存中读写文件
查看>>
使用pygal_maps_world.i18n中数据画各大洲地图
查看>>
sql server必知多种日期函数时间格式转换
查看>>
ListView如何获取点击单元格内容
查看>>
jQuery EasyUI 的下拉选择combobox后台动态赋值
查看>>
(转)游戏引擎中三大及时光照渲染方法介绍(以unity3d为例)
查看>>
timeline时间轴进度“群英荟萃”
查看>>
python map函数用法
查看>>
ios之申请后台延时执行和做一个假后台的方法(系统进入长时间后台后,再进入前台部分功能不能实现)...
查看>>
编码命名规范
查看>>