检验和计算——C语言

2023-05-16

一、计算检验和的步骤

检验和的计算都是一个模板,只是各种检验和的初始数据不一样
总结一下就是:求和、回卷、取反

  1. 把校验和字段设置为0。
  2. 求和:把需要校验的数据看成以16位为单位的数字组成,依次进行二进制求和。
  3. 回卷:求和后超过16位的加到低16位。
  4. 取反:最后结果取反码就是检验和。

(1)可以每两个求和后回卷,再求和,在回卷,直到全部求和,然后取反
(2)也可以全部求和,然后一直回卷直到高 16 位全部为 0,然后取反
一般采用第二种

另外UDP、TCP数据报的长度可以为奇数字节,因为计算时是16位为单位,所以此时计算校验和时需要在最后一个填充字节0(只是计算校验和用,不发送出去)。

二、接收端校验校验和步骤

把需要校验的内容(包括校验和字段)看成以16位为单位的数字,依次进行二进制反码求和,如果结果是0表示正确,否则表示错误。

三、说明

校验和覆盖的内容:

  1. IP首部校验和:IP首部
  2. ICMP校验和:ICMP首部+ICMP数据
  3. UDP、TCP校验和:首部+数据+12个字节伪首部(源IP地址、目的IP地址、协议、TCP/UDP包长)

四、IP首部校验和

1、结构图如下
在这里插入图片描述

2、详细计算过程
为了不出问题,按照报文格式依次编写数据即可
版本和首部长度放在一起

  • 版本:4
  • 首部长度:20字节 ==》 5
  • 总长度:46(首部 + 数据)
  • 标识:
  • 标志:是否分片,3 bit(不分片——010)
    (1) 一个比特保留为以后用;
    (2)第二个比特是DF(Don’t Fragment):“不分片”比特,若为1,IP将不对数据报进行分片,若无法将此数据报通过任何可用网络转发,则丢弃,并发送一个ICMP差错报文给起始端,若为0, 则在需要时将数据报分片;
    (3)第三个比特是MF(More Fragment):“更多分片”比特,为1,表示后面还有更多的分片,为0,则表示是最后的分片。
  • 偏移:偏移量,13 bit
  • 生存时间:64
  • 协议:17(UDP)
  • 检验和:置0
  • 源IP地址:192.168.1.81
  • 目的IP地址:192.168.1.166

然后把这些数据全部二进制相加求和,回卷,取反。得到校验和:0xa443

不分片
在这里插入图片描述
在这里插入图片描述

五、UDP校验和

1、结构图如下
在这里插入图片描述

2、详细计算过程
为了不出问题,按照报文格式依次编写数据即可

  • 源IP地址:192.168.1.81
  • 目的IP地址:192.168.1.166
  • 上层协议类型:17(UDP)
  • UDP长度:26(首部 + 数据)
  • 源端口:6081
  • 目的端口:7081
  • UDP长度:26(首部 + 数据)
  • 检验和:置0
  • 数据:81(18个,只是为了凑齐最小帧64字节)

然后把这些数据全部二进制相加求和,回卷,取反。得到校验和:0x6c2c
在这里插入图片描述
在这里插入图片描述

六、代码及解释(代码一样,只是初始数据不一样)

1、检验和是16 bit 的
2、

  • 数据有的是 8 位:所以两个一组,高位(在前面)左移8位(后面补0)变16 位,在后面 8 位加上低位,就组成了 16 bit
  • 数据有的是 16 位:直接相加

3、因为求和会溢出,所以声明一个 32 bit 来存放和,回卷就直接把高 16 位,加到低 16 位,直到高 16 位就变成 0,然后再强转格式即可。
4、最后要声明的是数据的个数

  • 偶数:直接相加
  • 奇数:最后一位左移 8 位
#include <stdio.h>
#include <malloc.h>

typedef unsigned char			uint8_t;	// 8  比特 
typedef unsigned short          uint16_t;	// 16 比特
typedef unsigned int            uint32_t;	// 32 比特
typedef unsigned long           uint64_t;	// 64 比特

//单个数据是:8 bit数据 ipv4 
uint8_t ipv4_8[] = {
	0x45,									//版本号 4,首部长度 20 字节 ==> 5
	0x00,									//服务类型,默认
	0x00, 0x2e,								//总长度(首部 + 数据)
	0x12, 0x34, 							//16 标识位 
	0x40, 0x00,								//3 比特标志不分片010 ,13 比特片偏移 
	0x40,									//生存时间 64
	0x11,									//上层协议,以 UDP 为例 17
	0x00, 0x00,								//首部校验和
	0xc0, 0xa8, 0x01, 0x51,					//源 IP 地址		192.168.1.81 
	0xc0, 0xa8, 0x01, 0xa6,					//目的地 IP 地址 	192.168.1.166
};
//单个数据是:8 bit数据 udp
uint8_t udp_8[] = {
	0xc0, 0xa8, 0x01, 0x51,					//源 IP 地址		192.168.1.81 
	0xc0, 0xa8, 0x01, 0xa6,					//目的地 IP 地址 	192.168.1.166
	0x00, 0x11,								//协议类型 UDP = 17 
	0x00, 0x1a,								//UDP 长度(首部 + 数据)

	0x17, 0xc1,								//源端口 
	0x1b, 0xa9,								//目的地端口 
	0x00, 0x1a,								//UDP 长度 
	0x00, 0x00,								//检验和置 0 

	0x51, 0x51, 0x51, 0x51, 0x51, 0x51,		//数据 18 字节 
	0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
	0x51, 0x51, 0x51, 0x51, 0x51, 0x51
};
//单个数据是:16 bit数据 ipv4 
uint16_t ipv4_16[] = {
	0x4500,	0x002e,
	0x1234, 0x4000,
	0x4011,	0x0000,
	0xc0a8, 0x0151,
	0xc0a8, 0x01a6,
};
//单个数据是:16 bit数据 udp 
uint16_t udp_16[] = {
	0xc0a8, 0x0151, 0xc0a8, 0x01a6,
	0x0011,	0x001a,	0x17c1,	0x1ba9,
	0x001a,	0x0000,	0x5151, 0x5151,
	0x5151,	0x5151, 0x5151, 0x5151,
	0x5151, 0x5151, 0x5151
};

uint16_t CheckSum_8(uint8_t array[], int len) {
	uint32_t sum = 0; 							    //32 比特,存放和 
	int i;
	for (i = 0; i < len - 1; i = i + 2) {           //高字节和低字节
		sum += ((uint16_t)array[i] << 8) + ((uint16_t)array[i + 1]);	//每 16 比特相加
	}
	
	if (i + 1 == len) {                             //如果位奇数,多出来的扩充字节至16 
		sum += (uint16_t)array[i] << 8;
	}
	
	while (sum >> 16) {								//直到高 16 比特全为 0,检验和在低 16 比特(一般一次就行了) 
		sum = (sum >> 16) + (sum & 0xffff);			//回卷 
	}
	sum += (sum >> 16);
	return (uint16_t)(~sum);					    //强制转换结果取反 
}

uint16_t CheckSum_16(uint16_t array[], int len) {
	uint32_t sum = 0;
	for (int i = 0; i < len - 1; i++) {				//16 比特直接相加(除最后一个)
		sum += array[i];
	}
	
	if (array[len - 1] >> 8) {						//判断最后一个是 0x00 还是 0x0000
		sum += array[len - 1];						//如果是 0x0000,直接加
	}
	else {
		sum += array[len - 1] << 8;					//如果是 0x00,移到高位相加
	}
	
	while (sum >> 16) {								//直到高 16 比特全为 0,检验和在低 16 比特(一般一次就行了) 
		sum = (sum >> 16) + (sum & 0xffff);			//回卷 
	}
	sum += (sum >> 16);
	return (uint16_t)(~sum);					    //强制转换结果取反 
}

int main() {
	int udp_len_8 = sizeof(udp_8) / sizeof(udp_8[0]);
	unsigned short check1 = CheckSum_8(udp_8, udp_len_8);
	printf("udp_8  检验和为:%x\n", check1);

	int udp_len_16 = sizeof(udp_16) / sizeof(udp_16[0]);
	unsigned short check2 = CheckSum_16(udp_16, udp_len_16);
	printf("udp_16 检验和为:%x\n", check2);

	int ipv4_len_8 = sizeof(ipv4_8) / sizeof(ipv4_8[0]);
	unsigned short check3 = CheckSum_8(ipv4_8, ipv4_len_8);
	printf("ipv4_8 检验和为:%x\n", check3);

	int ipv4_len_16 = sizeof(ipv4_16) / sizeof(ipv4_16[0]);
	unsigned short check4 = CheckSum_16(ipv4_16, ipv4_len_16);
	printf("ipv4_16检验和为:%x\n", check4);

	return 0;
}

在这里插入图片描述

七、wireshark抓包查看

待验证

八、其它

原码、补码、反码
正整数部分:
(1)原码、反码和补码都一样
负整数部分:
(1)原码和反码的相互转换:符号位不变,数值位按位取反
(2)原码和补码的相互转换:符号位不变,数值位按位取反,末位再加1

九、参考

1、IP首部校验和结果
https://wenku.baidu.com/view/c5ad9131581b6bd97f19ea85.html

IP首部检验和:2f01

uint8_t data[] = {				
    0x45, 0x00, 0x00, 0x30,		//IP 首部检验和 
    0x4a, 0x3e, 0x40, 0x00,
    0x80, 0x06, 0x00, 0x00,
    0xc0, 0xa8, 0x00, 0x37,
    0xc0, 0xa8, 0x00, 0x01
};

2、UDP校验和
https://blog.csdn.net/stone_yu/article/details/81611067

UDP检验和:285c

uint8_t data[] = {				
    0x0a,0xaa,0x3b,0xbf,		//UDP 检验和 
    0xd2,0x0e,0x96,0x0d,
    0x00,0x11,
    0x00,0x1c,
    0xd1,0x23,
    0x27,0x42,
    0x00,0x1c,
    0x00,0x00,
    0x6c,0x41,0x56,0x61,
    0x00,0x00,0x0e,0x00,
    0xf8,0xb6,0xd4,0x01,
    0x93,0x13,0x00,0x00,
    0x00,0x00,0x00,0x00
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检验和计算——C语言 的相关文章

  • QQ可以用十六进制登录哦

    又到装逼 时刻了 平常人登QQ是这样的 xff1a 如果我告诉你 xff1a 还可以这样登录 xff0c 你信吗 xff1f 显然我成功了 xff0c 你呢 xff1f 想知道如何快速把QQ号转换为十六进制吗 xff1f 评论里告诉你 xf
  • Keil C51详细安装教程(最新版)

    Keil C51 0x00 说在前面0x01 资源获取0x02 软件安装0x03 还有一步 xff08 重要 xff09 0x04 小问题 0x00 说在前面 x1f4e2 Keil 5常用的分两个版本 xff0c C51和MDK C51用
  • Java学习之JavaWeb篇

    图床路径 Kuang JavaWeb Java Web 1 基本概念 web开发 web xff0c 网页的意思 xff0c www baidu com静态web html xff0c css提供给所有人看的数据 xff0c 始终不会变化
  • Typora自动上传图片到Gitee图床

    Typora自动上传图片到Gitee图床 序言 思路 Gitee作为免费的图床 xff0c Typora作为最好用的blog博客笔记软件 xff0c 通过PicGo软件配置将Typora中的图片自动保存到Gitee图床 xff0c 获得云端
  • 关于百度OCR和EasyOCR的研究记录

    现行方案 xff1a 迅捷OCR软件 采用迅捷OCR文字识别软件 xff0c 购买了一年的期限 操作需要使用pyautogui来操作软件进行操作 xff0c 现在也可以使用USB鼠键模块KM3来真实模拟鼠标键盘的操作 xff0c 可信度更高
  • qt打开项目,只有pro文件其它文件消失:-1: error: msvc-version.conf loaded but QMAKE_MSC_VER isn‘t set

    之前在电脑打开开发的项目 xff0c 突然今天打开突然只有pro文件其它文件消失了 xff0c 在文件管理器里面找也都还有 打开项目只剩下蓝色框里面的 网上查了一些资料 xff0c 发现是开发程序事qt的版本不同所导致 解决方法 点开项目
  • 表格中重复项设置一级和二级序号排序

    摘要 xff1a 一级分类存在重复项 xff0c 需要排序 xff0c 二级分类也存在重复项 xff0c 也需要排序 xff0c 相同一级分类中的二级分类需要重新从一开始排序 xff08 重点和难点 xff09 先来看看效果 xff1a 公
  • 动态数码管显示实验

    文章目录 摘要实验器件简介实验原理硬件电路图硬件电路连线实验代码实验结果思考以及注意事项实验视频教程资源分享 摘要 本实验采用了普中科技的51单片机开发板 本实验以静态数码管显示实验为基础 https blog csdn net weixi
  • C51中intrins_h头文件解释分析

    文章目录 摘要源代码说明举个栗子 摘要 这是关于C51中使用循环移位等函数的头文件定义的分析 源代码 span class token comment INTRINS H Intrinsic functions for C51 Copyri
  • 喜马拉雅音频下载+x2m文件转换

    文章目录 摘要软件免费音频VIP音频 摘要 一款关于喜马拉雅音频的小神器 x2m格式转换为m4a格式 批量下载操作 软件 绿色免费的小工具ximalaya downloader amp x2m decoder xff0c 当然是在电脑上运行
  • http报错:405 (METHOD NOT ALLOWED)

    使用post请求ajax数据时 xff0c 报错 xff1a 405 METHOD NOT ALLOWED 将post请求改为get请求
  • Http怎么解决粘包拆包的?

    发送端 xff1a 应用层协议的每个包到达传输层 xff0c 如果是tcp xff0c 会可能出现以下情况 1 应用层的每个包被拆成多个tcp报文 xff0c 分别发送 xff0c 这是拆包 xff1b 2 应用层的多个包组成一个tcp报文
  • ROS TCP通信

    Reference https blog csdn net deyuzhi article details 51725074 https blog csdn net weixin 43795921 article details 85307
  • Ubuntu+ROS安装及rosdep init失败解决办法

    1 安装Ubuntu16 04 18 04 xff08 1 xff09 双系统硬盘安装 xff1a 参考双硬盘Window10与Ubuntu16 04 18 04安装 脚踩香蕉皮的博客 CSDN博客 Ubuntu 18 04 xff1a 链
  • c++ 编译 报错 未定义的引用

    遇到的问题有两种情况 一个是static没初始化 一个是模板类实现和定义分开写 这里主要记录一下模板类实现和定义分开写报错的问题 xff08 都放在 h文件中就不会报错 xff09 自己尝试用 传统 方法 xff0c 及在 h文件里声明 在
  • JNI基础语法

    一 Java和JNI类型对照 1 1 基本类型对照表 Java类型Native类型C C 43 43 类型大小Booleanjbooleanunsigned char无符号8位Bytejbytechar有符号8位Charjcharunsig
  • STL源码剖析 笔记之三 迭代器

    第三章 迭代器概念与traits编程技法 Design Patterns 中提供有23个设计模式的完整描述 迭代器模式定义如下 xff0c 提供一种方法 xff0c 使之能够依序巡防某个聚合物 容器 所含的各个元素 xff0c 而又无需暴露
  • 带复杂命令启停功能的二自由度自动进样器

    给8051发送 34 Start E 34 后 系统开始工作 发送 34 Stop E 34 后 系统停止工作 与之前以串口中断为主线的控制逻辑不同 这里以定时器0中断为主线 其实也就是以系统序列动作为主线 并提高了串口中断的优先级 以实时
  • Python温度转换实例

    我的第一个程序 xff1a TempCovert py TemStr 61 input 34 请输入带有符号的温度值 xff1a 34 if TemStr 1 in 39 F 39 39 f 39 C 61 eval TemStr 0 1

随机推荐

  • 不同数据类型所占字节

    一 32位处理器 xff1a char xff1a 1个字节 char p xff1a 4个字节 int xff1a 4个字节 unsigned int xff1a 4个字节 double xff1a 8个字节 short xff1a 2个
  • 浏览器中输入www.baidu.com后发生了什么

    一道经典的面试题 xff1a 你输入网址后到页面显示出来 xff0c 中间发生了什么 xff1f 第一步 浏览器查找该域名的 IP 地址 第二步 浏览器根据解析得到的IP地址向 web 服务器发送一个 HTTP 请求 第三步 服务器收到请求
  • 交换机对数据帧的处理规则

    一 概述 以太网交换机对二层帧的转发处理比较复杂 xff0c 很多同事都不是很清楚 本文将对此问题进行总结 xff0c 并通过实验进行验证 二 交换机基本概念 在了解交换机转发规则之前 xff0c 我们先理解交换机的一些概念 xff0c 如
  • NAT详解

    NAT详解 1 概述 1 1 nat简介 NAT xff08 Network Address Translation xff0c 网络地址转换 xff09 是1994年提出的 它是一个IETF Internet Engineering Ta
  • FTP服务

    1 FTP简介 FTP是File Transfer Protocol xff08 文件传输协议 xff09 的英文简称 xff0c 而中文简称为 文传协议 用于Internet上的控制文件的双向传输 同时 xff0c 它也是一个应用程序 x
  • 从Linux服务器下载文件夹到本地

    1 使用scp命令 把本地的source txt文件拷贝到192 168 0 10机器上的 home work目录下 scp home work source txt root 64 192 168 0 10 home work 把192
  • 安卓开发——网络传输工具类HttpUtil(基于okhttp3)使用

    AndroStudio开发 xff1a 使用时需先导入okhttp3依赖 xff1a com squareup okhttp3 okhttp 3 4 1 依赖导入步骤 xff1a File ProjectStructure Dependen
  • 无人系统传感器导航

    文章目录 GPS 全球定位系统 Global positioning system RTK Real time kinematic 距离传感器超声波传感器激光测距传感器毫米波雷达 Lidar Light detection and rang
  • 深度相机选取建议:

    2020 9 4更新 xff1a 现在再回头来看TOF应该会是未来 xff0c 限制TOF发展的硬件问题正在慢慢解决 苹果的ipad上也加上了TOF xff08 用于AR xff09 xff0c ipone12上估计也会有 可能小米的mix
  • JavaHTTP请求工具类HTTPUtils

    HTTP 请求工具类 HTTPUtils xff0c 其中涉及 HTTP 请求相关的各种操作 xff0c 关于这些方法详细的介绍可以查看这些博客 x1f4ac 相关 博客文章 Java发起HTTP请求并解析JSON返回数据 https bl
  • YOLOV7语义分割(日后自用笔记)

    系统win10 本文只是根据readme文件走流程 xff0c 记录一些常用公式 RizwanMunawar yolov7 segmentation at 87b016cda50371d6e2824378d641c2d4417ea1c3 g
  • char型和int型之间的类型转换

    char转换为int型数据 通过赋值方式将char类型变量转换为int型变量 xff0c 变量值为char类型变量的ASCII码值 例如 xff1a int a 61 0 那么打印a的结果为48 xff0c 如果想要得到正确的数字 xff0
  • ROS出现Cannot find source file的错误和add_dependencies,add_executable,target_link_libraries三者先后顺序不对所造成的错误。

    出现上面这个报错 xff0c 往往是 CMakeLists txt中的问题 add executable server tutorial ws src dynamic tutorials src server cpp 这行代码的问题 xff
  • 利用python ast包,绘制python代码的调用关系图(可分析互相调用的多个py文件)

    我的目的是辅助代码阅读 xff08 也方便写文档 xff09 xff0c 因此不需要太详细的信息 xff0c 只需要看用户定义的函数的函数调用关系 文章目录 1 开源项目staticfg的安装和直接使用2 绘制python的简单调用关系图
  • 1.3 Ubuntu18.04 ROS udp server 通信实现

    Ubuntu18 04 ROS udp Server通信实现 此小节介绍udp Server收发数据 udp通信属于帧传输 xff0c 在帧传输过程中对于消息的次序和到达情况没有需求 xff0c 没有进行校验 xff0c 所以UDP属于不可
  • 1.4 Ubuntu18.04 ROS udp Client通信实现

    Ubuntu18 04 ROS udp Client通信实现 此小节介绍udp Client收发数据 udp通信属于帧传输 xff0c 在帧传输过程中对于消息的次序和到达情况没有需求 xff0c 没有进行校验 xff0c 所以UDP属于不可
  • 1.5 Ubuntu18.04 ROS tcp/ip服务器与Android tcp/ip客户端通信

    Ubuntu18 04 ROS tcp ip服务器与Android tcp ip客户端通信 此小节介绍ubuntu18 04 ros tcp ip服务端与Android tcp ip客户端通信 xff0c 此操作可以使用安卓系统开发ROS机
  • Kerloud Mini发布,做开源技术的拥护者

    产品介绍 云讷科技团队在无人系统软硬件上有多年的行业积累 xff0c 经过一年多的努力 xff0c 团队已经完全实现了自主化飞控软硬件的研发 xff0c 并具备了全套产业链生产能力 新出品的Kerloud Mini飞行控制器是针对低成本无人
  • 2019年全国大学生电子设计竞赛G题解决方案-双路语音同传的无线收发系统

    今天 xff0c 今年的电赛的四天三夜的比赛时间已经结束了 xff0c 理论上已经不可以做板了 在这里分享一下我们做的G题的其中一个解决方案 xff08 我们做了三个方案 xff09 xff0c 思路等等 下面先说一下题目 xff1a 一
  • 检验和计算——C语言

    一 计算检验和的步骤 检验和的计算都是一个模板 xff0c 只是各种检验和的初始数据不一样 总结一下就是 xff1a 求和 回卷 取反 把校验和字段设置为0 求和 xff1a 把需要校验的数据看成以16位为单位的数字组成 xff0c 依次进