计算机网络学习笔记——IP Header Checksum(校验和)的计算方法

2023-05-16

从TCP/IP协议看到IP数据报,看到Checksum的算法描述,不甚了了。

The checksum field is the 16 bit one’s complement of the one’s complement sum of all 16 bit words in the header. ————RFC791

1、怎么算IP Header Checksum?

百度百科里对校验和的解释提到了:1的补码和(one’s complement sum)就是带循环进位(end round carry)的加法,在最后对累加结果取反码。
其实这里讲得很清楚了,但不完全清楚。因为对1的补码和到底怎么算,理解错了。

  1. 最开始是按照学数电时对反码加法的理解,即正数的反码等于原码,负数的反码由原码的按位(除了符号位保持为1)取反得到。错。
  2. 百科最后有附的程序,感觉第10行代码是迷之取反。按这个思路求的结果也不对。

百科所附C语言程序

  1. 找到一个求IP Header Cheaksum的正确方法:
    1. 把划分出所有的16bit数据逐个相加,一旦有进位,就把它加到最低位。
    2. 最后把结果所有位按位取反。
  2. 又找到一个等价的方法:IP数据报首部校验和算法 详细 非代码(接收方检验结果有笔误,但总体写得很棒!)
    1. 所有数据逐个相加(使用32位的int类型)
    2. 把高16位右移16位,再与低16位相加。循环该步,直至结果的二进制表示不超过16位。

2、反码究竟是什么?怎么可以这样用?

可行的方法找到了,可为什么是这样的呢?就像这篇博客里说的那样,这些16bit数据谈不上有正负号,没有什么符号位,一律按位取反,跟加减算数里的用法相去甚远。

首先根据一下表格明确各个概念:

名称英文名称直译名称
反码one’s complement1的补码
补码two’s complement2的补码

然后看一下维基百科对ones’ complement的解释

The ones’ complement of a binary number is the value obtained by inverting all the bits in the binary representation of the number (swapping 0s and 1s). This mathematical operation is primarily of interest in computer science, where it has varying effects depending on how a specific computer represents numbers.
A ones’ complement system or ones’ complement arithmetic is a system in which negative numbers are represented by the inverse of the binary representations of their corresponding positive numbers. In such a system, a number is negated (converted from positive to negative or vice versa) by computing its ones’ complement. An N-bit ones’ complement numeral system can only represent integers in the range −(2N−1−1) to 2N−1−1 while two’s complement can express −2N−1 to 2N−1−1. It is one of three common representations for negative integers in microprocessors, along with two’s complement and sign-magnitude.
The ones’ complement binary numeral system is characterized by the bit complement of any integer value being the arithmetic negative of the value. That is, inverting all of the bits of a number (the logical complement) produces the same result as subtracting the value from 0.

第一段黑体处明确指出1补是所有位按位取反,
第二段黑体部分说1补运算系统中负数表示为对应正数的反码。

由此可知,1补就是所有位取反的一个操作,应用在运算中可以方便负数的表示和运算,但这并非其全部用法

3、反码求和为什么循环进位?

反码求和(one’s complement sum):循环进位。先求和再取反,与先取反再求和,结果是一样的。
那反码求和为什么是循环进位呢?
可以查看问题 为什么二进制反码加减要循环进位?为什么补码加减不需要循环进位?下的回答。其中有分类讨论,讲得非常棒!
最后也猜了下Checksum使用1补的原因。

4、接收端怎么检验,正常结果应该是什么?

接收端收到IP数据报的时候也这么算。
因为Checksum存了其他数据的和的反码(Checksum初始化为0x0000,虽然参加了运算,但跟没参加一样),其他数据之和加上本身的反码,就是0xFFFF,即-0,再取反就是0x0000,即+0
(补充:反码表示负数时,有两个零,补码只有一个零,可以比反码多表示一个负数)

5、Java代码简单实现

java代码如下:

package cn.it.test;

public class CheckSum {
    public static void main(String[] args) {
        int[] msg = {0x9C1A, 0xDA88, 0xAD35, 0x0000};
        System.out.println(checkSum(msg));
    }

    /**
     * IP Header Checksum
     * @param msg 数组中的每一个数都是16bit的
     * @return 返回16进制的字符串
     */
    public static String checkSum(int[] msg) {
    	// one's complement sum 带循环进位的加法
        int sum = 0;
        for (int m : msg) {
            sum += m;
            if (sum > 0xFFFF) {
                sum &= 0xFFFF;
                ++sum;
            }
        }
		
		// one's complement 每一位都按位取反
        sum = ~sum;
        sum &= 0xFFFF;

        return String.format("0x%04x",sum);
    }
}

6、补充简洁的解释

后来查1补的用法时,看到这个回答,非常简洁。

一个例子就是求校验和(Checksum) 通俗一点来讲是:

  1. 先是 one’s complement sum,将data按16位分组,所有组相加,再将进位值加到结果的末位。
  2. 再是 one’s complement,结果取反码。

7、总结

  1. 会求Checksum了
  2. 打破了之前对反码的刻板认识
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机网络学习笔记——IP Header Checksum(校验和)的计算方法 的相关文章

  • 如何手动设置 HTTP_X_FORWARDED_FOR 的值?

    我在某处读到他们说 当您想要记录用户的 IP 时 HTTP X FORWARDED FOR 不是受信任的变量 因为他们可以更改它 这是真的吗 如何 正如答案中指出的here https stackoverflow com questions
  • Safari 11 X-XSRF-TOKEN 刷新后未更新

    最近 Mac OSX 上的 Safari 11 发布 此更新导致我们的 Web 应用程序与请求标题上的 XSRF 结合出现问题 我将尝试以逻辑方式描述问题 好的情况应该是这样的 当用户想要登录时 他会收到服务器的响应 其中包含包含 XSRF
  • module.exports 将所有函数包含在一行中

    这是一个后续问题在 Node js 中 如何 包含 其他文件中的函数 https stackoverflow com questions 5797852 in node js how do i include functions from
  • 文件的 CRC 检查

    我正在使用一个小型 FAT16 文件系统 并且想要为存储配置信息的单个 XML 文件生成 CRC 值 如果数据发生更改或损坏 我希望能够检查 CRC 以确定文件仍处于原始状态 问题是 如何将CRC值放入文件中 而不改变文件本身的CRC值 我
  • 标头包含深度限制[重复]

    这个问题在这里已经有答案了 我想知道 包含头文件时 包含文件的深度可以无限增加吗 你能在编译时指定一个限制吗 Example main c include A h const int xyz CONST VALUE A h include
  • 我可以 #include 定义 DWORD 的最小 Windows 标头是什么?

    我自己有一个小头文件 它声明了几个函数 其中一个函数的返回类型为DWORD 我舍不得拖进去windows h只是为了获得此类型的官方定义 因为该文件很大 并且我的标头将在许多不需要它的源模块中使用 当然 在实践中我知道DWORD只是unsi
  • 操作 TCP 标头中 ISN 编号的最有效方法 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我目前正在尝试编写一个程序 该程序将
  • .cpp 文件和 .h 文件有什么区别?

    因为我已经做了 cpp文件 然后将它们传输到 h文件 我能找到的唯一区别是你不能 include cpp文件 我缺少什么区别吗 C 构建系统 编译器 不知道有什么区别 所以这都是约定之一 约定是 h文件是声明 并且 cpp文件是定义 这就是
  • Bootstrap 3 导航栏 - 无法正确折叠

    导航栏曾经正常工作 但我做了一些更改 它不再工作 当我将窗口缩小时 会显示切换方块 但是当我单击它时 什么也没有发生 Note 导航栏在全屏下工作正常 它只是在小窗口中 当我单击切换按钮时 下拉菜单不会出现 想知道是否有人知道如何解决它 这
  • 在所有页面中正确包含 php 标头

    我会包含一个 php 标头 mysite com header php 在站点的所有页面中 怎样做才正确呢 有相关链接 这没有帮助 你可以这样做 include SERVER DOCUMENT ROOT header php
  • 强制下载 tar 存档的标头

    我的服务器上有一个 tar 存档 必须可以通过 php 下载 这是我使用过的代码 content file get contents tar header Content Type application force download he
  • c 中导入的头文件使用了哪些函数?

    我正在阅读这个用 C 编写的庞大代码库 在某些文件中包含一些标头 但未指定其需要 我想知道是否有任何方法可以查看当前文件中的特定标头使用了哪些函数 而无需阅读两个文件中的整个代码 最简单的方法是检查预处理文件 编译器的预处理器将生成声明或定
  • 如何在 Maven 中创建校验和然后将其输出到文本文件?

    还在学习如何使用Maven 我想知道是否有办法做到checksum在生成的WAR file The Maven目标是package 我想要实现的是得到一个checksum价值 包装的WAR文件 与打包文件一起放入文本文件中 提前致谢 让它与
  • Python urllib2 响应头

    我正在尝试提取 URL 请求的响应标头 当我使用firebug分析URL请求的响应输出时 它返回 Content Type text html 但是当我使用 python 代码时 urllib2 urlopen URL info 结果输出返
  • 这个校验和算法可以改进吗?

    我们有一个非常旧的 不受支持的程序 可以跨 SMB 共享复制文件 它有一个校验和算法来确定文件内容在复制之前是否已更改 该算法似乎很容易被愚弄 我们刚刚找到了一个示例 其中两个文件完全相同 除了单个 1 更改为 2 之外 返回相同的校验和
  • mpi.h:使用未定义的类型?

    我正在尝试将 OpenMPI 的 mpi h 的重要部分翻译为 D 编程语言 以便我可以从 D 调用它 HTOD 根本不起作用 我无法理解以下代码段 typedef struct ompi communicator t MPI Comm O
  • JPEG 标头丢失/损坏

    我有一个 130kb jpeg 图像 无法在任何程序中打开 我需要修复它 从我使用的各种图像恢复软件中 我得到的只是 图像头损坏 丢失 当我查找文件的属性时 我什至没有得到任何信息 没有尺寸等 只有文件大小 一旦图像的标头丢失 是否可以恢复
  • Javascript CRC16 示例代码或实现

    有人可以分享一个链接或示例代码来实现 JavaScript 中字符串的校验和吗 预先非常感谢 你想要什么 你需要更具体 CRC16 算法数量众多 每种算法都有自己的多项式并用于特定用途 一些 CRC16 算法非常适合创建哈希 例如 对于 R
  • 如何传递对象的数组列表来填充每个部分标题文本及其内容?

    我在用粘性网格标题 https github com TonicArtos StickyGridHeaders对于带有部分的 GridView 这个库正在使用R array countries填充GridView使用提供的数据并从传递的字符
  • 删除 PHP 中的标头

    为了允许缓存 PHP 生成的文件 我想确保 Pragma no cache 标头是not放 但是 如何删除可能已经设置的标头 这就对了could有可能 有人在代码中的某个地方写了header Pragma no cache 现在我想确保标头

随机推荐

  • 软件设计原则:迪米特法则

    一 定义 迪米特法则 xff1a 要求一个对象应该对其他对象有最少的了解 xff0c 所以又叫做最少知识原则 二 法则内容 xff1a 1 不该有直接依赖关系的类之间 xff0c 不要有依赖 xff1a 即 xff0c 不和陌生人说话 xf
  • ElasticSearch最佳入门实践(六十二)type底层数据结构

    type xff0c 是一个index中用来区分类似的数据的 xff0c 类似的数据 xff0c 但是可能有不同的fields xff0c 而且有不同的属性来控制索引建立 分词器 field的value xff0c 在底层的lucene中建
  • 四轴的组成及参数评定

    电气工程及其自动化专业 xff0c 坐标广东湛江 xff0c 大一时期对专业上很感兴趣 xff0c 自学了许多东西 xff0c 但是只是停留在理论基础上而缺乏实践 xff0c 和学校在这方面的普及有点关系吧 xff0c 趁着国家有这方面的支
  • sudo rosdep init报错的解决方式

    Ubuntu16 04下安装ROS时 xff0c 执行到sudo rosdep init这一步时会遇到问题 xff0c 如下图所示 xff1a 尝试了很多办法 xff0c 都没有成功的 后来参考了https www ioiox com ar
  • VS版本和VC版本的对应【完整版】

    看到网上杂七杂八 xff0c 很乱 xff0c 索性自己发帖多版本开发福音 xff08 该帖不更新了 xff0c 请看参考里连接中的官方文档 xff0c 非常清楚 xff0c 还保持最新 xff09 MSC 1 0 MSC VER 61 6
  • 搭建运行激光slam环境中遇到的问题

    1 先是踩了一些坑 xff0c 重复安装了一些库 xff0c 因为ros noetic里面就自带了一些库 xff0c 所以安装的时候重复安装了 解决方法 xff1a 删掉重装 另外缺少一些库 xff0c 乱装一顿 xff0c 居然凑齐 Ub
  • mac上用VSCode搭建 c++ 工程,用于学习Opengl

    先下载VSCode安装c c 43 43 插件 xff0c 安装微软这个 创建一个文件夹作为项目 xff0c 然后用VSCode打开这个目录在这个文件夹中创建好四个目录 xff0c 分别是src xff0c lib include bin
  • 刷赞与评论

    网站自动刷帖 xff0c 刷赞 xff0c 刷评论等网络推广方式的基本实现 里面的思路有东西
  • 系统复制-快速重装系统

    ubuntu 直接把安装好常用软件和环境的系统打包成镜像 xff0c 用systemback安装 xff0c 便捷很多 之前那种 xff0c ubuntu安装都要好久 xff0c 少说也得20分钟吧 xff0c 之前就是等 xff0c 等它
  • 机器人 控制领域

    机器人 控制领域好像没太有很新很有用的工作 xff0c 还是依据Dynamic Model的Motion Planning更接近于任务层 其实 xff0c 感觉自己喜欢的不是控制 而是motion xff0c motion control
  • 树莓派电压过低 串口数据错误增多

    调试过程中 xff0c 树莓派串口读单片机上传的数据 的程序突然一堆checksum error 换一块满电的LiPo电池就大幅减少了报错 一开始猜测原因 可能是电压过低导致CPU运行慢了 xff08 可能叫做 降频 xff09 xff0c
  • 机器人知识体系

    纲 机电力算控感 知识体系体系各元素特点体系的建立和完善 机电力算控感 知识体系 机械 电子电气 力学 xff08 静力学与动力学分析 流体力学 材料力学等 xff09 计算 xff08 通用计算机和嵌入式计算机 xff09 控制理论 感知
  • OpenCV之imwrite()等基本操作

    参考 xff1a Opencv之imwrite 函数的用处 imwrite 函数用来保存图片 opencv3中的imwrite函数是用来输出图像到文件 xff0c 其声明如下 xff1a CV EXPORTS W bool imwrite
  • 麦克纳姆轮全向移动原理

    什么是麦克纳姆轮 在竞赛机器人和特殊工种机器人中 xff0c 全向移动经常是一个必需的功能 全向移动 意味着可以在平面内做出任意方向平移同时自转的动作 为了实现全向移动 xff0c 一般机器人会使用 全向轮 xff08 Omni Wheel
  • 卡尔曼滤波(KF)与扩展卡尔曼滤波(EKF)的一种理解思路及相应推导(1)

    前言 xff1a 从上个世纪卡尔曼滤波理论被提出 xff0c 卡尔曼滤波在控制论与信息论的连接上做出了卓越的贡献 为了得出准确的下一时刻状态真值 xff0c 我们常常使用卡尔曼滤波 扩展卡尔曼滤波 无迹卡尔曼滤波 粒子滤波等等方法 xff0
  • Qt Cmake添加*.qrc资源文件

    cmake minimum required VERSION 3 5 project Test LANGUAGES CXX 这里 file GLOB RECURSE QRC SOURCE FILES CMAKE CURRENT SOURCE
  • IOS 加载本地HTML

    web qtt以 folder形式添加到项目中 xff0c 注意是蓝色的颜色 创建swift项目 xff0c 写入如下代码 span class token comment span span class token comment Vie
  • C#实现:将十进制数转换为十六进制(含完整源码)

    C 实现 将十进制数转换为十六进制 含完整源码 在C 中 我们可以使用基础数据类型来存储整数值 如int long等 而十进制数是我们最常用的数制 但有些场景下需要将其转换为其它进制 如十六进制 本文将介绍如何使用C 来实现将十进制数转换为
  • 怎样用串口发送结构体-简单协议的封包和解包

    先说解决方案 xff0c 细节和实现代码都放在正文 下位机 xff1a 把结构体拆分成8位的整型数据 xff0c 加上数据包头和包尾 xff0c 然后按顺序单个单个地发出 xff1b 上位机 xff1a 把串口里的数据读取出来 xff0c
  • 计算机网络学习笔记——IP Header Checksum(校验和)的计算方法

    从TCP IP协议看到IP数据报 xff0c 看到Checksum的算法描述 xff0c 不甚了了 The checksum field is the 16 bit one s complement of the one s complem