校验和之概念、计算原理、检验原理、实例计算、代码编程,力荐力荐力荐

news2024/11/17 23:30:58

阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量。文章设置为仅粉丝可见,是因为写博客确实花了不少精力。不用担心你关注我而我却不关注你,因为我是个诚信互关的人!!互相进步谢谢!!

文章目录

  • 阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量。文章设置为仅粉丝可见,是因为写博客确实花了不少精力。不用担心你关注我而我却不关注你,因为我是个==诚信互关==的人!!互相进步谢谢!!
  • 1、背景介绍
  • 2、校验和
  • 3、运算机制(教材)
  • 4、运算机制(总结)力荐力荐力荐!!!
  • 5、校验和计算例子(力荐力荐力荐!!!)
  • 6、编程之求校验和(力荐力荐力荐!!!)

1、背景介绍

Windows下进行socket编程时遇到的关于校验和的问题,先记录如下。


2、校验和

TCP/IP 体系中有两种校验机制:CRC 校验与校验和,用于保证消息的完整性。CRC 校验用于整个以太网帧的校验,32 位的校验码被添加到以太网帧的最后四个字节。更为常用的是校验和机制,被用于 IP,ICMP,TCP,UDP 等三四层协议中。

IP、ICMP、TCP、UDP等协议的校验和算法都是相同的,采用的都是将数据流视为16位整数流进行重复叠加计算。


3、运算机制(教材)

网上版本绕来绕去,不要去看,直接看谢希仁的《计算机网络》教材,上图。
图1,文字描述
在这里插入图片描述 图2,流程图描述 在这里插入图片描述


4、运算机制(总结)力荐力荐力荐!!!

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

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

2、把需要校验的数据看成以16位为单位的数字组成,依次进行二进制反码算术运算相加(网上很多说“反码求和”,不准确!原因见下方说明);

3、得到的和取反,再存放至校验和字段。

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

1、把首部看成以16位为单位的数字组成,用反码算术运算求和(包括校验和字段);
2、和取反;
3、检查计算出的校验和的结果是否为0。如果等于0,校验和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。

说明:

  • 1、要掌握反码算术运算的概念:

    以反码算术运算的加法为例。

    0和0相加是0,0和1相加是1,1和1相加是0但要产生一个进位1,加到下一列。若最高位相加后产生进位,则最后得到的结果要加上溢出的进位1(可能是多个1)。

    而补码相加的话溢出位不会去考虑!!!

  • 2、“利用反码算术运算求和 ,再取反” == “反码求和”:

    计算校验和的第二步,网上提到很多“反码求和”,包括教材上解释 “反码算术运算” 也提到了反码求和。这点很容易绕,我的理解如下。

    利用反码算术运算求和,再取反。其实是直接拿计算机内部存储的数字(补码),把补码直接利用反码算术运算相加,再把和取反;

    二进制反码求和。就是先把这数(此时以补码存储)取反,然后求和,如果最高位有进位,则向低位进1;

    先取反后相加,先相加后取反,得到的结果是一样的。因此“利用反码算术运算求和 ,再取反” == “反码求和”。而往往后者电脑执行更快,所以实现代码都是先相加,最后再取反,这也就是书上讲后者的原因了,因为是对照代码来的。

  • 3、计算机内部存储,原码、反码、补码

    上面谈到了计算机内部数字的存储,见《原码、反码、补码:概念、计算机内部表示、实例、运算及转换规则、使用原因》。所以验证了,书上给的计算校验和步骤,其实是利用补码进行反码算术运算的相加,再取反得到的。

  • 4、接收方校验的原理

    这一点网上有两个版本,“全0正确” or “全1正确”。其实这与实现方式有关。书上既然以“全0正确”,那就以这个为标准咯。

  • 5、为什么接收方计算出来全0才正确?

    理解之前,需要知道如下运算法则

    A + ~A =1,例如
    	01101001
    +	10010110
     ——————————————
        11111111
    

    为方便看,假设报文头被分为4个16位,值分别是A、B、C、D,其中第二个16位设为校验和字段。这里假设没有溢出位,有溢出位的也可自行验证符合。

    发送方计算校验和
    	第一步:校验和字段置0,并依次求和。
    	sum = A + 0 + C + D
    	第二步:取反。
    	check_sum = ~(A + C + D)= B
    接收方校验
    	第一步:全部求和
    	A + B + C + D = (A + C + D ) + [ ~(A + C + D)] =1
    	第二步:取反
    	~1 = ~0
    

5、校验和计算例子(力荐力荐力荐!!!)

wireshark抓到的ICMP报文如下

08 00 4d 5a 00 01 00 01 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 61 62 63 64 65 66 67 68 69
其中校验和是“4d 5a”

1、将校验和字段置为0

08 00 00 00 00 01 00 01 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 61 62 63 64 65 66 67 68 69

2、把它们两个字节(16bit)组成一组,依次以二进制相加(求和)直至得到结果,这里我就不用二进制表示了,直接用十六进制好看,但要清楚计算机内部是利用二进制处理的。

0800 + 0000 + 0001 + 0001 + 6162 + 6364 + 6566 + 6768 + 696a + 6b6c + 6d6e + 6f70 + 7172 + 7374 + 7576 + 7761 + 6263 + 6465 + 6667 + 6869 = 6b29f = b2a5(处理溢出位,即b29f + 6 = b2a5)

3、取反

~b2a5 & 0xffff --> 4d5a


6、编程之求校验和(力荐力荐力荐!!!)

这里以c语言为例。

版本1

//计算校验和 版本1  参考微软Ping源码
/*
步骤: 
1、将报文分成两个字节一组,如果总字节数为奇数,则在末尾追加一个零字节;
2、对所有 双字节 进行按位求和;
3、将高于 16 位的进位取出相加,直到没有进位;
4、将校验和按位取反;

心得:
1、先取反后相加,先相加后取反,得到的结果是一样的。后者更高效,因此实现代码都是先相加,最后再取反。 
2、关于求校验和时处理溢出位。可以在循环里面加进位(版本2),也可以等全部循环结束了再加(版本1); 
3、处理进位时是通过双目运算符<<或>>操作进行的; 
4、反码算术运算可参加计网教材  
*/
USHORT checksum(USHORT *buffer, int size) {
	unsigned long cksum=0;
	while(size >1) {
		cksum+=*buffer++;
		size -=sizeof(USHORT);
	}
	if (size)               //buffer中的数据是奇数个字节
		cksum += *(UCHAR*)buffer;
	cksum = (cksum >> 16) + (cksum & 0xffff);   //完成了所有数的累加后,开始处理进位。将所有数完成求和后,统一将高 16 位(溢出数)加到低 16 位(求和数)
	cksum += (cksum >>16);   //在完成上一次操作后,可能又发生了溢出,再执行一次同样的操作。有溢出,加的是溢出数,没有溢出,加0000,相当于没有加
	return (USHORT)(~cksum);  //取反
}
/*
这里存在两个问题:
首先16bit 数累加时,如果有 2^16 个数累加,那么会使 32 位数本身发生溢出,
但好在目前人类还没提出这么长的协议,所有不用担心 32 位数的溢出问题。

其次,如果将溢出数与结果数累加后,有可能再次溢出 1 ,所以在完成第一次高 16 位与低 16 位的运算后,需要再进行一次该运算,
第二次运算不可能产生溢出。(可以用最极端的情况考虑下 16bit 全1 与 16bit 全1 进行运算)
*/

版本2

//计算校验和 版本2  参考https://fasionchan.com/network/icmp/ping-c/
/*
心得:
这里移位操作可能看不懂,其实就是左移右移来进行倍数的扩大,从而拼接起来,实现8位变16位
*/
uint16_t calculate_checksum(unsigned char* buffer, int bytes) {
    uint32_t checksum = 0;
    unsigned char* end = buffer + bytes;  //buffer相当于指向头,end相当于指向尾
    // 奇数字节加上最后一个字节并重置结束
    if (bytes % 2 == 1) {
        end = buffer + bytes - 1;
        checksum += (*end) << 8;  //最后一个字节左移8位,从而实现最后一个字节后面补0,再加上去
    }
    // 逐个相加,这里处理进位就是在循环里处理,当然也可以在循环外
    while (buffer < end) {
        checksum += (buffer[0] << 8) + buffer[1];//第一个字节左移8位,再加上第二个字节,从而实现两个8位变16位
        // 添加进位(如果有)
        uint32_t carray = checksum >> 16;  //右移16位,相当于把进位单独拎出来了,从而加上去
        if (carray != 0) {
            checksum = (checksum & 0xffff) + carray;
        }
        buffer += 2;
    }
    // 取反
    checksum = ~checksum;
    return checksum & 0xffff;
}

说明:
双目运算符移位操作符不懂的看之前写的笔记《从代码角度理解:C语言中的 “左移<<“ 与 “右移>>“》。


参考链接:
《深入LwIP(一):校验和机制》
《小菜学网络:用C语言开发ping命令》
《用C语言实现ping命令》
《如何计算icmp校验和》

码字不易,谢谢点赞!诚信互关,诚信互关,诚信互关!!!
码字不易,谢谢点赞!诚信互关,诚信互关,诚信互关!!!
码字不易,谢谢点赞!诚信互关,诚信互关,诚信互关!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何用LightningChart创建Android图表数据可视化应用程序?(下)

LightningChart JS 是一款高性能的 JavaScript 图表工具&#xff0c;专注于性能密集型、实时可视化图表解决方案。 LightningChart .JS | 下载试用&#xff08;qun&#xff1a;740060302&#xff09;https://www.evget.com/product/4189/download 在上一篇&#xff0c;我们介…

CDN是什么?用了CDN就一定比不用更快吗?

对于开发同学来说&#xff0c;CDN这个词&#xff0c;既熟悉又陌生。 平时搞开发的时候很少需要碰这个&#xff0c;但却总能听到别人提起。 我们都听说过它能加速&#xff0c;也大概知道个原因&#xff0c;但是往深了问。 用了CDN就一定比不用更快吗&#xff1f; 就感觉有些…

Node.js操作Dom ,轻松hold住简单爬虫

前言 前段时间&#xff0c;我发现一个开源题库&#xff0c;题目非常有意思。我想把它整成一个JSON文件做为数据储备&#xff0c;方便整活。 一共有一百五十多道题目&#xff0c;手动CV我肯定是不想干的。于是写了个脚本&#xff0c;在写脚本的过程中&#xff0c;我发现一个能…

Opencv(C++)笔记--利用分水岭算法实现图像分割

1--分水岭算法的原理详细原理讲解可参考&#xff1a;博客1和视频1&#xff1b;原理简述&#xff1a;分水岭算法的基本思想是把图像视为拓扑地貌&#xff0c;图像中每一点像素的灰度值表示该点的海拔高度&#xff0c;每一个局部极小值及其影响区域称为集水盆&#xff0c;而两个集…

csrf漏洞原理及防御

攻击原理 从上图可以看出&#xff0c;要完成一次CSRF攻击&#xff0c;受害者必须依次完成两个步骤 1.登录受信任网站A&#xff0c;并在本地生成Cookie 2.在不登出A的情况下&#xff0c;访问危险网站B 防御原理 csrf能防御的本质是&#xff0c;黑客虽然携带了合法的cookie&a…

振弦采集模块的辅助功能寄存器

振弦采集模块辅助功能寄存器 1.频率值模拟量输出 VMXXX&#xff08;仅 VM501、 VM511&#xff09; 模块支持将当前实时频率值以模拟量形式从管脚输出&#xff0c;模拟量有电流和电压两种输出形式。为了使用此功能&#xff0c;需要将辅助功能寄存器 AUX.[0]设置为 1&#xff0…

<Linux开发> ubuntu开发工具-EasyConnect使用记录

&#xff1c;Linux开发&#xff1e; ubuntu开发工具-EasyConnect使用记录 1、安装EasyConnect 打开EasyConnect官网EasyConnect 根据当前电脑系统选择对应版本下载 作者这里是ubuntu 22.04版本 右击&#xff0c;选择 “软件安装” 即可安装完成&#xff1b;windows版本类似…

数据可视化:揭开“智慧校园”新篇章,助力新时代教育信息化

随着移动互联网、物联网等新一代信息技术的快速发展&#xff0c;建设智慧校园已经具备了成熟的技术条件。自从教育部启动教育信息化2.0计划后&#xff0c;建设智慧校园已成为我国教育信息化发展目标&#xff0c;无论是国家教育事业发展的十三五规划&#xff0c;还是十四五规划&…

Hadoop高手之路7-Hadoop的新特性

文章目录Hadoop高手之路7-Hadoop的新特性一、Hadoop2.0以上新特性二、Yarn资源管理框架1. yarn体系结构2. yarn的工作流程三、HDFS的高可用HA1. HDFS的高可用&#xff08;HA&#xff09;架构2. 搭建Hadoop高可用HA集群1) 规划集群节点2) 环境准备3) 配置HA集群(1) 修改core-sit…

【ROS】—— ROS通信机制——实践与练习(六)

文章目录前言1. 话题发布1.1 C方式实现1.2 python实现2. 话题订阅2.1 C实现2.2 python实现3. 服务调用3.1 C3.2 python4. 参数设置4.1 C4.2 python4.3 运行4.4 其他方式4.4.1 修改小乌龟节点的背景色(命令行实现)4.4.2 启动节点时&#xff0c;直接设置参数4.4.3 通过launch文件…

Java测试框架——JUnit详解(45)

文章目录前言何为JUnit&#xff1f;官方资料JUnit4常用注解和断言代码测试搭建一个JUnit测试环境生命周期忽略测试断言测试异常测试测试时间套件测试JUnit5JUnit5对比JUnit4的好处导包的改变注解的改变扩展JUnit新功能&#xff1a;参考文章JUnit是Java编程语言的单元测试框架&a…

list的介绍及模拟实现

&#x1f308;感谢阅读East-sunrise学习分享——list的介绍及模拟实现 博主水平有限&#xff0c;如有差错&#xff0c;欢迎斧正&#x1f64f;感谢有你 码字不易&#xff0c;若有收获&#xff0c;期待你的点赞关注&#x1f499;我们一起进步 今天想分享介绍一下STL的容器之一lis…

openharmony GPIO 驱动开发

openharmony GPIO 驱动开发GPIO 基础知识GPIO 基础知识——概念GPIO 基础知识——IO 复用GPIO 基础知识——GPIO 分组和编号GPIO 基础知识——用户态测试HDF 框架下 GPIO 驱动HDF 框架下的 GPIO 驱动——案例描述(以 HI3516DV300 平台为例&#xff0c;提供代码)HDF 框架下的 GP…

为什么jvm需要有栈协程?

旧有的servlet生态的线程模型 首先我们先要聊一聊现在我们用的最多的servlet的执行模型是什么&#xff1a; 这个dispatch其实就是一个EventLoop或者说是一个selector来检测注册到其上的链接状态发生的变化 以Tomcat为例子&#xff0c;当这个selector发现存在一个链接可读时&…

【node.js】fs\path\http模块的使用

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;Node.js的fs\path\http模块的使用&#xff0c;模块化开发概念 目录 一、node.js概念与作…

一个曾经分享动态(2021)的回顾和解释-2023-

虽然看过一些典故&#xff0c;里面有名言道&#xff1a; 解释永远是多余的&#xff0c;理解的人不需要&#xff0c;不理解的更不需要。 但是&#xff0c;误会还是需要沟通来消除的。 例如&#xff0c;曾经分享过&#xff1a; 如下都是误会 ↓↓↓↓↓↓↓↓↓ 有朋友联系我&a…

解决东方财富数据接口激活后仍显示reactive的问题

首先确保代码可以在python中导入这个包&#xff1a; from EmQuantAPI import c如果无法导入&#xff0c;就是python没有配置好东方财富的接口&#xff0c;可以参考&#xff1a; Mac版本&#xff1a;Mac使用Python接入东方财富量化接口Choice&#xff0c;调试与获取数据Window…

北京智和信通:信创运维自动化,全栈适配国产软硬件环境

近年来&#xff0c;新基建和信创产业政策东风席卷神州&#xff0c;国产CPU、操作系统、关键应用软件等核心技术步入发展快车道&#xff0c;一批优秀软硬件产品走进政府机关、国企事业单位。在国产软硬件核心技术崛起的过程中&#xff0c;如何迅速搭建起成熟的生态环境是行业面临…

LeetCode135之分发糖果(相关话题:数组,贪心思想)

题目描述 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0c;计算并返回需…

【node.js】跨域的解决办法(CORS方法、同源策列的理解)

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;面对cors跨域、同源策略的处理 下图为本文的核心 目录 一、 跨域介绍 二、同源策略 三…