
《计算机网络》校验和_文档.doc
12页计算机网络课程设计实验报告题目:计算校验和班级:2009级教育技术学一班作者: 郭建勋200930680106 林泽涛200930680113 张丽丽200930680127指导老师: 完成时间:2011年12月16日华南农业大学 信息学院目录1、题目概述 31.1 题目: 31.2 题目要求 32、开发的基础知识 32.1 计算校验和 32.2 一些编码技术可以提高校验和的计算速度 43、设计思路 53.1 数据的输入方式 53.2 校验和的计算 54、程序流程图 75、程序源代码 86、开发过程 117、程序运行情况 118、总结 128.1林泽涛的心得体会 128.2郭建勋的心得体会 121、题目概述1.1 题目:校验和的计算过程分为三个步骤:数据文件的输入,校验和的计算以及效验结果的输出计算校验和应用最为普遍的是端循环进位法:将数据按一定数位进行累加,最高位的进位则循环加入最低位待教研的数据按16位为一个单位相加,采用端循环进位,最后对所得16位的数据取反码因为待教研的数据是以字节方式分隔的,所以为了方便,将16位的数据分成高8位和低8位分别处理该算法的代码如下:endaroundcarry(int & highbyte, int & lowbyte){ while(highbyte>0xff||lowbyte>0xff) { lowbyte+=(highbyte>>8); highbyte=highbyte&0xff); highbyte+=(lowbyte>>8); lowbyte=lowbyte&0xff); } }1.2 题目要求课程设计要求:根据上面介绍的算法,编制程序为给定数据计算校验和。
1)以命令行形式运行:check_sum infile其中check_sum为程序名,infile为输入数据文件名2)输出:数据文件的校验和2、开发的基础知识2.1 计算校验和有很多数学方法可以用来提高校验和的计算速度,下面我们将就此展开讨论2.1.1 交换性与结合性因为校验和主要考虑被校验数据中所包含字节数量的是奇数还是偶数,所以校验和的计算可以以任意顺序进行,甚至可以把数据进行分组后再计算例如,用A、B、C、D,……,Y,Z分别表示一系列八位组,用[a,b]这样形式的字节来表示a*256+b的整数,那么16位校验和就可以通过以下形式给出:[A,B]+’[C,D]+’……+’[Y,Z] [1][A,B]+’[C,D]+’……+’[Z,0] [2]在这里,+’代表1补数加法,即将前面的16位校验和按位取反[1]可以以([A,B]+’[C,D]+’……+’[J,0]+’([0,K]+’……+’[Y,Z]) [3]的形式进行计算2.1.2 字节顺序的自主性打破被校验数据中的字节顺序仍可以计算出正确的16位校验和。
例如,我们交换字节组中两字节的顺序,得到[B,A]+’[D,C]+’……+’[Z,Y] [4]所得到的得结构与[1]式是相同的(当然结果也是要进行一次反转的)为什么会是这样呢?我们发现两种顺序获得的进位是相同的,都是从第15位到第0位进位以及从第7位到第8位进位这也就是说,交换字节位置只是改变高低位字节的排列顺序,但并没有改变它们的内在联系因此,无论底层的硬件设置中对字节的接收顺序如何,校验和都可以被准确地校验出来例如,假设校验和是以主机序(高位字节在前低位字节在后)计算的数据帧,但以网络序(低位字节在前高位字节在后)存放在内存中每一个16位的字中的字节在传送过程中都交换了顺序,在计算校验和之后仍会先交换位置再存入内存,这样就与接受到的原本以网络序存储的数据帧中的校验和项保持一致了2.1.3 并进行计算某些机器的字处理长度是16位的倍数,这样可以提高它的计算速度由于加法所具有的结合性,我们没有必要按照顺序对每个字节进行累加相反,我们可以利用这一特点对它们进行并行累加并行地计算校验和只是增加了每次累加的信息长度例如,在一个323位的机器上,我们可以一次增加4个字节,即[A,B,C,D]+’……。
计算结束后再把累加和“折叠”起来,把一个32位的数值变为16位,这样产生的新的进位也要循环累积起来此外,在此仍不考虑字节顺序的问题,我们可以用’[D,C,B,A]+’……或[B,A,D,C]+;……这样的顺序来计算校验和,最终再通过交换16位校验和中的字节序来得到正确的值这些改变顺序的方法都是为了让所有的偶数字节进入一个校验和字节,所有的奇数字节进入一个校验和字节2.2 一些编码技术可以提高校验和的计算速度2.2.1延迟进位法这种方法在主要的累加循环结束之后再把进位累加进和值其实现方式就是用32位的累加器获得16位校验和,这样溢出就产生在高16位上这种方法避免了累加器中进位传感器机构的设置,但是它要求的容量是原来的累加器容量的两倍,因此它更多地依赖于硬件条件2.2.2反向循环法这种方法可以减少由循环而产生的负荷,有效地展开内部的累加循环,把循环过程中的一系列加法命令复制下来这种技术通常可以节省大量的时间,但是程序的逻辑设计会比较复杂2.2.3合并数据拷贝法计算校验和以及读入数据都需要将数据从内存的一个位置转移到另一个位置,这样会占用内存总线的带宽,而内存总线的传输效率是提高校验和计算速度的瓶颈,尤其是对于某些机器(如一些简单的慢速的微型机)来说,这一问题尤为严重。
为了解决这个问题,可以把数据读入的过程与校验的过程合二为一,也就是在读入数据的同时计算校验和,这样就可以省去一次数据移动的过程,从而提高校验和的计算速度3、设计思路3.1 数据的输入方式输入数据可能是以字符形式存储的,而校验和的计算则要采用数据形式,所以在从文件读取数据时,都要进行字符到数据的相互转换1) 将读入的ASCII码转化为相应的整型变量if(ch>=’0’&&<=’9’)ch-=’0’;elseif(ch>=’a’&&ch<=’f’)ch=ch-‘a’+10;elseif(ch>=’A’&&ch<=’F’)ch=ch-‘A’+10;2) 在使用C++编程时直接使用16进制的方式打开输入文件Ifstream in(argv[1],ios::nocreate);i.setf(ios::hex);3.2 校验和的计算校验和算法是本程序的核心部分,在2.5节中我们介绍了一些相关的算法,而应用最为普遍的是端循环进位法端循环进位的算法如下:将数据按一定数位进行累加,最高位的进位则循环加入最低位待校验的数据按16位为一个单位相加,采用端循环进位,最后对所得16位的数据取反码因为待校验的数据是以字节方式分隔的,所以为了方便,将16位的数据分成高8位和低8位分别处理。
该算法的代码如下:endaroundcarry(int &highyte,int &lowbyte){ while(highbyte>0xff||lowbyte>0xff)0 //高8位或低8位中的任何一方产生了溢出(进位) { lowbyte+=(highbyte>>8); //低字节加上高字节超过8位的进位 highbyte=highbutr&0xff; //清除高字节的进位 highbyte+=(lowbyte>>8); //高字节加上来自低字节的进位 lowbyte=lowbyte&0xff; //清除低字节的进位 }4、程序流程图程序开始,初始化ch,count,sum,checksum从文件读取一个字符chch=EOF?ch=’ ’ch转换为相应的8为数据,count++count偶数?ch低4位送入chr高4位ch低4位送入chr低4位得到chr值(count/2)%2=1?chr和sum高8位相加chr和sum低8位相加得到sum值将32位sum折叠到16位YYYNYN求sum反码并输出结束5、程序源代码#include












