原文链接:http://blog.chinaunix.net/uid-26758209-id-3146230.html

校验和算法

经常看计算机网络相关的书时,每次看到关于IP或者是UDP报头校验和时,都是一笑而过,以为相当简单的东西,不就是16bit数据的相加吗!最近在学习Ping命令的源待时,看到里面有关于校验和的算法。一头雾水,后来查找资料,看到校验和是16bit字的二进制反码和。总是觉得很奇怪,为什么会用反码和,而不是直接求和呢?或者是补码和呢?因为在计算机里面数据是以补码的形式存在啊!经过看书查资料,下面总结一些这个校验和算法具体是怎么实现的。

首先,IP、ICMP、UDP和TCP报文头都有检验和字段,大小都是16bit,算法基本上也是一样的。

在发送数据时,为了计算数据包的检验和。应该按如下步骤:

1、把校验和字段设置为0;

2、把需要校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和;

3、把得到的结果存入校验和字段中

在接收数据时,计算数据包的检验和相对简单,按如下步骤:

1、把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;

2、检查计算出的校验和的结果是否为0;

3、如果等于0,说明被整除,校验和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。

虽然说上面四种报文的校验和算法一样,但是在作用范围存在不同:IP校验和只校验20字节的IP报头;而ICMP校验和覆盖整个报文(ICMP报头+ICMP数据);UDP和TCP校验和不仅覆盖整个报文,而且还有12个字节的IP伪首部,包括源IP地址(4字节)、目的IP地址(4字节)、协议(2字节)、TCP/UDP包长(2字节)。另外UDP、TCP数据报的长度可以为奇数字节,所以在计算校验和时需要在最后增加填充字节0(填充字节只是为了计算校验和,可以不被传送)。

在UDO传输协议中,校验和是可选的,当校验和字段为0时,表明该UDP报文未使用校验和,接收方就不需要校验和检查了!那如果UDP校验和的计算结果是0时怎么办?书上有一句话:“如果校验和的计算结果为0,则存入的值为全1(65535),这在二进制反码计算中是等效的”

那么校验和到底怎么计算了?

1、什么是二进制反码求和

对一个无符号的数,先求其反码,然后从低位到高位,按位相加,有益处则向高位进1(和一般的二进制法则一样),若最高位有进位,则向最低位进1.

首先这里的反反码好像和以前学的有符号反码不一样,这里不分正负数,直接每个为都取反。

上面加粗的那句话和我们平时的加法法则不一样,最高位有进位,则向最低位进1。确实有些疑惑,为什么要这样呢?自习分析一下,上面的这种操作,使得在发送加法进位溢出时,溢出值并不是10000,而是1111.也即是当相加结果满1111时溢出,这样也可以说明为什么0000和1111都表示0了。

下面是两种二进制反码求和的运算:

原码加法运算:3(0011)+5(0101)=8(1000)

8(1000)+9(1001)=1(0001)

反码加法运算:3(1100)+5(1010)=8(0111)

8(0111)+9(0110)=2(1101)

从上面的例子中,当加法未发生溢出时,原码与反码加法运算结果一样;当有溢出时,结果就不一样了,原码是满10000溢出,而反码是满1111溢出,所以相差正好是1.

另外,关于二进制反码求和运算需要说明的一点是,先取反后相加与先相加后取反,得到的结果是一样的。

2、校验和算法实现

代码如下:

USHORT checksum (USHORT *buffer,int size)

{

Unsigned long cksum=0;

While (size>1)

{

Cksum +=*buffer++;

size -=sizeof(USHORT);

}

If (size)

{

Cksum +=*(UCHAR *) buffer;

}

//将32位转换为16位

While (cksum>>16)

Cksum = (cksum>>16) + (cksum & 0xffff);

Return (USHORT) (~cksum);

}

buffer是指向需要校验数据缓冲区的指针,size是需要检验数据的总长度(字节为单位)。

4-13行代码是对数据按16bit累加求和,由于最高位的进位需要加在最低位上,所以cksum必须是32位的unsigned long型,高16bit用于保存累加过程中的进位;另外代码10~13行是对size为奇数情况的处理。

14~16行代码的作用是将cksum高16bit的值加到低16bit上,即把累加中最高位的进位加到最低位上。这里使用了while循环,判断cksum高16bit是否非零,因为第16行代码执行的时候,还是可能向cksum的高16bit进位。

有些地方是通过下面两条代码实现的:

Cksum = (cksum >> 16) + (cksum & 0xffff);

Cksum  += (cksum >> 16);

这里只进行了两次相加,即可保证相加后cksum的高16位为0,两种方式的效果是一样,事实上,上面的循环也最多执行两次!

17行代码即对16bit数据累加的结果取反,得到二进制反码求和的结果,然后函数返回该值。

3、为什么使用二进制反码求和呢?

为什么要使用二进制反码来计算校验和呢,而不是直接使用原码或者是补码呢?

在谷歌上找到一篇相关的文章:

上面是原文的一部分,说明在TCP/IP校验和中使用反码求和的一些优点:

a、 不依赖系统是大端小端。即无论你是发送方计算机或者接收方检查校验和时,都不要调用htons或者ntohs,直接通过上面的算法就可以得到正确的结果。这个问题你可以自己举个例子,用反码求和时,交换16位数的字节顺序,得到的结果相同,只是字节顺序相应地也交换了;而如果使用原码或者补码求和,得到的结果可能就不同。

b、 计算和验证校验和比较简单、快递。

计算机网络二进制反码求和校验算法相关推荐

  1. 二进制反码求和校验算法

    原文链接:http://blog.chinaunix.net/uid-26758209-id-3146230.html 校验和算法 经常看计算机网络相关的书时,每次看到关于IP或者是UDP报头校验和时 ...

  2. 计算机网络之Nagle算法与延迟确认

    文章目录 计算机网络之Nagle算法与延迟确认 1.Nagle算法 2.延迟确认 计算机网络之Nagle算法与延迟确认 1.Nagle算法 如果发送方疯狂地向接收方发送很小的数据包,比如一次就发送 1 ...

  3. TCP/IP 中的二进制反码求和算法

    对于这个算法,很多书上只是说一下思路,没有具体的实现.我在这里举个例子吧. 以4bit(计算方便一点,和16bit是一样的)做检验和来验证. 建设原始数据为      1100   ,   1010 ...

  4. 计算机网络 --- 网络层路由算法与路由协议

    路由表: 最佳路由: "最佳"只能是相对于某一种特定要求下得出的较为合理的选择而已. 路由算法的分类 静态路由算法(非自适应路由算法) 管理员手工配置路由信息.简便,可靠,在负荷稳 ...

  5. 计算机网络--路由表生成算法

    路由表 路由表是指路由器或者其他互联网网络设备上存储的一张路由信息表,该表中存有到达特定网络终端的路径,在某些情况下,还有一些与这些路径相关的度量. 在Linux下可以使用route查看路由表: 其中 ...

  6. 计算机网络生成树算法,生成树算法

    在图论的数学领域中,如果连通图G的一个子图是一棵包含G的所有顶点的树,则该子图称为G的生成树(SpanningTree).生成树是连通图的包含图中的所有顶点的极小连通子图.图的生成树不惟一.从不同的顶 ...

  7. 计算机网络 洪泛算法,泛洪

    泛洪(Flooding)是交换机和网桥使用的一种数据流传递技术,将从某个接口收到的数据流向除该接口之外的所有接口发送出去 中文名 泛洪 外文名 Flooding适用范围 交换机和网桥 领    域 信 ...

  8. 计算机网络路由讲解,计算机网络:路由算法详解(网络层)

    路由算法 路由表对于路由器的重要性不言而喻,维护一个高效的路由表则是路由器提高性能的主要方式. 路由算法将网络抽象成一张无向带权图(数据结构概念),将路由器抽象为节点,路由器间的连接关系抽象为边.图的 ...

  9. 计算机网络基础——路由算法

    路由控制有各种各样的算法,其中最具代表性的有两种,是距离向量算法(Distance-Vector)和链路状态算法(Link-State) 一.距离向量算法 距离向量算法是根据距离(代价)和方向决定目标 ...

最新文章

  1. docker-registry的定制和性能分析
  2. 全网最详细的Xshell或SecureCRT下spark-shell里出现无法退格或者删除的问题现象的解决办法(图文详解)...
  3. Juce源代码分析(一)Juce的优势
  4. Vue 脚手架生成的项目结构分析||Vue 脚手架的自定义配置
  5. 机会只留给有准备的人
  6. realmeq参数配置详情_小米11什么时候发布 小米11参数配置详情
  7. 什么是 SAP UI5 的 Hybrid Web Containers
  8. Azure DevOps Server (TFS)中代码文件换行问题解决方案(Git)
  9. 应用百花齐放,呈现北浙苏沪粤五极格局丨2021年中国区块链产业发展报告产业应用篇...
  10. 2019数据安装勾选_建筑CAD首选软件~【T20 天正建筑 V5.0 安装教程】
  11. 图的遍历:BFS算法学习
  12. 档案管理制度计算机管理制度,计算机管理档案制度
  13. css3技巧——实现一个正方体
  14. 最佳eclipse字体推荐(个人认为)
  15. pytorch_geometric(pyg)复现T-GCN
  16. POJ 1392 Ouroboros Snake (欧拉回路)
  17. 提升用户体验?指示性设计元素不可或缺
  18. 在阿里云服务器发邮件
  19. vue项目中的小知识--快捷键-vue插件版本号--vscode插件等
  20. 安装程序检测出计算机内含有下列,图文帮您win10系统安装ps提示:安装程序检测到计算机处于挂起状态的解决教程...

热门文章

  1. gitlab ci cd流程
  2. Unity ECS实例:制作俯视角射击游戏!
  3. 查看计算机id和密码,ID号可以查询很多信息,并迅速去当地更改密码
  4. MySQL数据迁移到新目录_mysql数据目录迁移
  5. 微信小程序搜索框自动补全功能
  6. 双系统Ubuntu 引导修复(Boot Repair)
  7. Linux 利器- Python 脚本编程入门(一)
  8. 优客工场携手首旅如家 双巨头开启创享办公空间新模式
  9. 学生计算机使用计算度方法是,计算器的使用对小学生学习数学的影响
  10. linux快捷键及主要命令(转载)