ZJU164-Software CRC

[题目大意]
        你在一家拥有很名个人计算机的公司上班。你的老板,Penny Pincher博士,想要把这些个人计算机联网,但是他又不想花钱买网卡。你无意中告诉了老板每台计算机出厂时就带有一个异步串行端口,老板当然把脑防动到这个不用花钱的解决方案上。于是指派你完成编写通信软件的任务,以实现计算机之间联网。
你阅读了许事美手通信的书籍,知道在传送及接收信息时容易产生错误。解决间题的典型的方法是,在信息的术尾附加错误校验信息。该信息允许接收程序校验传送的信息是否有错误产生(在大多数情况下)。于是,你跑到图书馆借了一本厚厚的关于通信的书利用周末(当然没有加班费)研究情误校验方法。
       最后,你决定CRC(Cyclic Redundancy Check)是最适合的错误校验方案.井向PennyPincher博土详细描述了该错误校验方案.
将待传递的信息看作是“ 串很长的二进制数。信息的第个字 节(Byte)是这个二进制数的最高有效字节,第二个字节是第二个最高有效字节,依此类推。把这个二进制数称为“m".传送信息时,会在“m”之后加上2个字节的CRC校验码,整个二进制数称为“m2”.
选择CRC校验码的方法:当"m2”除以某个16位的值"g”时,余数为0.这样就使接收程序比较容易判断信息是否产生了传送错误。所以对接收到的任何信息除以“g”.如果余数为0即代表此信息正确。
     注意,大部分书中都建议“g”的值为奇数.你决定用34943作为“g”的值

输入
必须设计一个算法,对所有传送的信息计算CRC的值。为了测试算法的正确性,编写一个程序读取数据(每行都是字符,不包括行结束符)。对每一行信息,计算相应的CRC值.并输出该CRC值(十六进制).占一行。对每行输人,不会超过1024个ASCII字符。当- .行的第一列是#时,代表输人结束。
输出
    对每组测试数据输出行,是以十六进制表示的CRC值。注意:CRC的取值范围应该是0到34942(十进制)之间。

样例输入

this is a test

 

A

#

样例输出

77 FD

00 00

0C 86
 【程序代码】

#include<stdio.h>
#define Generator 34943
int main()
{
	unsigned char c, flag;
	int count;//一行中的字符数
	//CRC数据结构
	union
	{
		unsigned int L;
		struct
		{
			unsigned char b1;
			unsigned char b2;
			unsigned char b3;
			unsigned char b4;
		}CRC;
	}data;
	while (1)
	{
		count = 0;
		//计算一行所有的字符,除以Generator的余数
		data.L = 0;
		while (scanf("%c", &c) &&c!= '\n')
		{
			count++;
			flag = c;
			//采用每个字符取模的方法(将计算结果移到高位,后面两个字节存放CRC)
			data.L = ((data.L << 8) + c) % Generator;
		}
		//将发送信息的余数,移到整数最高和次高字节
		data.L = (data.L << 16) % Generator;
		if (data.L != 0)data.L = Generator - data.L;
		if (count == 1 && flag == '#')break;
		printf("%02X %02X\n", (int)data.CRC.b2, (int)data.CRC.b1);
	}
	return 0;
}

 

                                                                   

                                   L(联合体) 
b4b3b2(CRC高位字节)b1(CRC低位字节)

知识点总结:

移位运算符

"<<" 左移运算符:将左侧运算符的二进制位按右侧制定的数值进行移位,移位的方向是向左移动,每移动一位,原左侧的二进制位自动丢弃,低位补零(相当于原来的数被乘以2);

">>"右移运算符:该操作符当操作数向右移位,最右侧的位被丢弃,左侧最高位补0.(相当于将原来的数除以2);

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值