校验和算法

2023-05-16

原文链接: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、 计算和验证校验和比较简单、快递。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

校验和算法 的相关文章

  • Opencv之Aruco码的检测和姿态估计

    1 介绍 Aruco码是由宽黑色边框和确定其标识符 id 的内部二进制矩阵组成的正方形标记 它的黑色边框有助于其在图像中的快速检测 xff0c 内部二进制编码用于识别标记和提供错误检测和纠正 单个aruco 标记就可以提供足够的对应关系 x
  • linux与window文件通过串口传输方法(zmod传输方法)

    我们在调试linux产品时 xff0c 有的产品没有网口 xff0c 只有串口 这时nfs tfp都用不了 只能用串口来传输文件 把windows上文件通过串口传输到开发板上 开发板和电脑通过串口连接 2 使用MobaXterm工具 xff
  • CentOS 7 需要安装的常用工具,及centos安装fcitx 搜狗输入法的坑旅

    Centos常用设置 1 当最大化时隐藏标题栏 或者使用tweak tool 在字体中将标题栏字体设置为0 建议这个方法 2 添加epel源 yum y nogpgcheck install http download fedoraproj
  • 小学数学公式大全

    小学数学公式大全 第一部分 xff1a 概念 1 加法交换律 xff1a 两数相加交换加数的位置 xff0c 和不变 2 加法结合律 xff1a 三个数相加 xff0c 先把前两个数相加 xff0c 或先把后两个数相加 xff0c 再同第三
  • c++中的点号(.),冒号(:)和双冒号(::)运算符

    1 冒号 xff08 xff09 用法 xff08 1 xff09 表示机构内位域的定义 xff08 即该变量占几个bit空间 xff09 typedef struct XXX unsigned char a 4 char型的字符a占4位
  • C++ 对象和实例的区别,以及用new和不用new创建类对象区别

    起初刚学C 43 43 时 xff0c 很不习惯用new xff0c 后来看老外的程序 xff0c 发现几乎都是使用new xff0c 想一想区别也不是太大 xff0c 但是在大一点的项目设计中 xff0c 有时候不使用new的确会带来很多
  • 巫泽俊...《挑战程序设计竞赛》算法及相关书籍论点

    为什么要参加程序设计竞赛 能提高程序设计能力 xff0c 掌握技巧 减少错误 xff1b 能结识更多的同好 xff0c 交流切磋 xff1b 能更好地推销自己 xff08 大赛的前几名往往受到世界知名公司的青睐 xff09 秋叶拓哉认为 x
  • (struct)结构体变量作为函数参数调用的方法小结

    结构体变量 结构指针变量 结构数组作为函数的参数应用实例分析 struct stud long int num float score 结构体变量作为函数的参数 xff0c 修改之后的成员值不能返回到主调函数 void funvr stru
  • 搭建nginx反向代理用做内网域名转发

    基于域名的7层转发的实现 xff08 NAT 43 反向代理 xff09 在实际办公网中 xff0c 因为出口IP只有一个 xff0c 要实现对外提供服务的话就必须得做端口映射 xff0c 如果有多个服务要对外开放的话 xff0c 这只能通
  • 从平面上最近的点对,谈谈分治算法

    首先介绍一下分治 xff08 Divide and Conquer xff09 算法 xff1a 设计过程分为三个阶段 Divide xff1a 整个问题划分为多个子问题 Conquer xff1a 求解各子问题 递归调用正设计的算法 Co
  • NOIP2017 国庆郑州集训知识梳理汇总

    第一天 基础算法及数学 基本算法 递推 递归 分治 二分 倍增 贪心 递推 指通过观察 归纳 xff0c 发现较大规模问题和较小规模问题之间的关系 xff0c 用一些数学公式表达出来 在一些题解中 xff0c 和 计数DP 是指同一个概念
  • 挑战程序设计竞赛 — 知识总结

    准备篇 1 5 运行时间 概述编写的目的是面向ACM程序设计竞赛 xff0c 不可避免的要涉及复杂度和运行时间的问题 xff0c 本节给出了解决问题算法选择的依据 假设题目描述中给出的限制条件为n lt 61 1000 xff0c 针对O
  • 阿里巴巴笔试题选解

    阿里巴巴笔试题选解 9月22日 xff0c 阿里巴巴北邮站 小题 xff1a 1 有三个结点 xff0c 可以构成多少种二叉树形结构 xff1f 2 一副牌52 张 去掉大小王 xff0c 从中抽取两张牌 xff0c 一红一黑的概率是多少
  • 腾讯2014软件开发笔试题目

    腾讯2014软件开发笔试题目 9月21日 xff0c 腾讯2014软件开发校招 简答题 广州 简答题 xff1a 1 请设计一个排队系统 xff0c 能够让每个进入队伍的用户都能看到自己在 中所处的位置和变化 队伍可能随时有人加入和退出 x
  • MAVLink简介

    MAVLink简介 Mavlink协议最早由 苏黎世联邦理工学院 计算机视觉与几何实验组 的 Lorenz Meier于2009年发布 xff0c 并遵循LGPL开源协议 Mavlink协议是在串口通讯基础上的一种更高层的开源通讯协议 xf
  • C/C++ 服务器程序(从入门到精通)

    Windows 服务被设计用于需要在后台运行的应用程序以及实现没有用户交互的任务 为了学习这种控制台应用程序的基础知识 xff0c C xff08 不是C 43 43 xff09 是最佳选择 本文将建立并实现一个简单的服务程序 xff0c
  • 图像处理常用算法(C++/OPENCV)

    添加椒盐噪声 void salt Mat amp src int number for int i 61 0 i lt number i 43 43 int r 61 static cast lt int gt rng uniform 0
  • 【解决linux下连接向日葵失败或连接之后断开的解决方案】

    解决linux下连接向日葵失败或连接之后断开的解决方案 linux在软件中搜索lightdm桌面管理器并安装即可 xff01

随机推荐

  • 机器学习推荐系统评价指标之AUC

    机器学习推荐系统评价指标之AUC 综述AUC的计算过程AUC的优势 综述 AUC是机器学习模型中常见评价指标 xff0c 在推荐系统中也十分常见 和常见的评价指标Acc xff0c P xff0c R相比 xff0c AUC具备一定的优势
  • 多线程访问同步方法情况

    文章目录 1 多线程访问同步方法1 1 两个线程同时访问一个对象的同步方法1 1 1 代码演示1 1 2 运行结果 1 2 两个线程访问的是两个对象的同步方法1 2 1 代码演示1 2 2 运行结果 1 3 两个线程访问的是synchron
  • 剑指 Offer 33. 二叉搜索树的后序遍历序列

    题目描述 xff1a 输入一个整数数组 xff0c 判断该数组是不是某二叉搜索树的后序遍历结果 如果是则返回 true xff0c 否则返回 false 假设输入的数组的任意两个数字都互不相同 参考以下这颗二叉搜索树 xff1a 5 2 6
  • 求解空间两个三维坐标系之间的变换矩阵

    三维刚体变换模型 即旋转 平移矩阵 RT矩阵 的估计方法 原理简单阐述 只要算出变换矩阵 就可以算出A坐标系的一个点P在坐标系B里的对应点坐标 即 T为3x3的转换矩阵 t 为3x1的位移变换向量 这里点坐标均为3x1的列向量 非齐次形式
  • Ubuntu下网络调试助手 NetAssist

    近期在ubuntu下开发一个网络相关的程序 之前在windows上开发时 xff0c 一直使用NetAssist这个小工具 xff0c 简洁实用 所以就安装了一个对应版本的网络调试助手 NetAssist 下载地址 xff1a 链接 xff
  • 程序员裸辞三个月,终于拿到大厂offer!网友:不应该!

    一个行业发展成熟 xff0c 必定会重新洗牌 xff0c 就像朝代的更替一样 xff0c 现在互联网发展就是遇到了这样的瓶颈期 xff0c 出现了衰退 xff0c 就形成大家口中所说的 互联网寒冬 但是有技术的人哪里怕过寒冬 xff0c 所
  • HttpUtils 用于进行网络请求的工具类

    用于进行网络请求的工具类 xff0c 可进行get xff0c post两种请求 xff0c 值得一提的是这个utils给大家提供了一个回调接口 xff0c 方便获取下载文件的进度 span class hljs keyword impor
  • deepin系统

    https www uc23 net xinwen 76259 html 据介绍 xff0c 深度操作系统 xff08 deepin xff09 自 2015 年开始 xff0c 就放弃基于 Ubuntu 作为上游 xff0c 选择 Ubu
  • 学习日志2

    这几天一直在思考如何解决摄像头与vins与fast planner如何相结合再应用的问题 因为摄像头是因特尔的D435i xff0c 于是决定在gazebo上实现D435i的仿真 由于D435I版本较新 xff0c 因此github上基本没
  • 学习日志3

    这几天准备用分别用ego planner与fast planner进行飞行仿真 本来准备在双系统的ubuntu上安装ego planner xff08 之前ubuntu上已经安装过vins fusion vins mono与fast pla
  • 学习日志5

    最近老师让我阅读了一篇新文章 xff0c 文章标题如下图 文章通过解决时间分配问题以及通过模型预测轮廓同时控制问题控制 xff08 MPCC xff09 优化能够使四旋翼无人机找到最优轨迹 xff0c 可以快速地避障 xff0c 速度甚至可
  • 万字长文 | 阿里大佬 ssp offer 的后台服务器开发学习路线

    前言 小北去年经历春秋招 xff0c 拿到了不少大厂 offer xff0c 其中包括 sp ssp 等 xff0c 感觉在复习准备校招上还是有一定方法的 xff0c 因为我自己是 Linux C C 43 43 路线 所以这一篇的主题是
  • 看完谷歌大佬的刷题笔记, 我直接手撕了200道 Leetcode 算法题

    如果你刷leetcode觉得吃力 那么一定需要这份谷歌大佬的leetcode刷题笔记 在这里推荐一个谷歌大佬的刷题笔记 每一道题的题解都写得非常清楚 作者在美国卡内基梅隆大学攻读硕士学位时 xff0c 为了准备实习秋招 xff0c 他从夏天
  • JVM中的栈区域

    一 栈 xff1a 在JVM中也叫栈内存 xff0c 主要负责java程序的运行 xff0c 栈在线程创建时被创建 xff0c 栈时线程私有的 xff0c 也即每一个线程都有自己的栈空间 xff0c 线程之间的运行不受影响 相互独立 二 栈
  • 初步认识ADRC(自抗扰控制)与应用

    这是一个目录 ADRC的基本原理一 参考资料推荐二 为什么PID好 xff0c 以及 xff0c 为什么PID不够好1 为什么PID好 不依赖于模型的控制器2 为什么PID不够好 PID的缺点 三 ADRC给出的方案 如何保留PID的优点
  • 先进非线性控制方法 INDI 快速部署到PX4用于四旋翼控制(part2)

    目录 一 PX4 v11 的姿态控制解析1 角度环控制2 角速度环控制3 控制分配 二 简易INDI如何部署到PX41 获取角加速度 和 电机转速测量值 xff08 1 xff09 角加速度 xff08 2 xff09 转速 2 具体实现过
  • ubuntu18.04 cv2.VideoCapture无法读取视频

    源代码 xff1a span class token comment 读取视频 span span class token keyword import span cv2 video file span class token operat
  • 关于字符串结束标志‘\0‘的一些见解

    前言 本人是一个刚刚上路的IT新兵 菜鸟 分享一点自己的见解 如果有错误的地方欢迎各位大佬莅临指导 如果这篇文章可以帮助到你 劳请大家点赞转发支持一下 一 39 0 是什么 xff1f 0 是转义字符 xff0c 为了告诉编译器 0 是空字
  • gRPC 基础(二)-- Go 语言版 gRPC-Go

    gRPC Go Github gRPC的Go实现 一个高性能 开源 通用的RPC框架 xff0c 将移动和HTTP 2放在首位 有关更多信息 xff0c 请参阅Go gRPC文档 xff0c 或直接进入快速入门 一 快速入门 本指南通过一个
  • 校验和算法

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