北邮机试 | bupt oj | 98. IP数据包解析

心得

我真就喜欢无脑分割字符串。。。
利用while(1)死循环,对char类型的两种情况的处理。
另外,有个易错点:对于char类型,在格式转换时,是不好直接和c<'10’比较的,顶多比到9,这我都能犯错。。裂开

题目

IP数据包解析
时间限制 1000 ms 内存限制 65536 KB

题目描述
我们都学习过计算机网络,知道网络层IP协议数据包的头部格式如下:
在这里插入图片描述

其中IHL表示IP头的长度,单位是4字节;总长表示整个数据包的长度,单位是1字节。

传输层的TCP协议数据段的头部格式如下:

在这里插入图片描述

头部长度单位为4字节。

你的任务是,简要分析输入数据中的若干个TCP数据段的头部。 详细要求请见输入输出部分的说明。

输入格式
第一行为一个整数T,代表测试数据的组数。

以下有T行,每行都是一个TCP数据包的头部分,字节用16进制表示,以空格隔开。数据保证字节之间仅有一个空格,且行首行尾没有多余的空白字符。

保证输入数据都是合法的。

输出格式
对于每个TCP数据包,输出如下信息:

Case #x,x是当前测试数据的序号,从1开始。

Total length = L bytes,L是整个IP数据包的长度,单位是1字节。

Source = xxx.xxx.xxx.xxx,用点分十进制输出源IP地址。输入数据中不存在IPV6数据分组。

Destination = xxx.xxx.xxx.xxx,用点分十进制输出源IP地址。输入数据中不存在IPV6数据分组。

Source Port = sp,sp是源端口号。

Destination Port = dp,dp是目标端口号。

对于每个TCP数据包,最后输出一个多余的空白行。

具体格式参见样例。

请注意,输出的信息中,所有的空格、大小写、点符号、换行均要与样例格式保持一致,并且不要在任何数字前输出多余的前导0,也不要输出任何不必要的空白字符。

输入样例
2
45 00 00 34 7a 67 40 00 40 06 63 5a 0a cd 0a f4 7d 38 ca 09 cd f6 00 50 b4 d7 ae 1c 9b cf f2 40 80 10 ff 3d fd d0 00 00 01 01 08 0a 32 53 7d fb 5e 49 4e c8
45 00 00 c6 56 5a 40 00 34 06 e0 45 cb d0 2e 01 0a cd 0a f4 00 50 ce 61 e1 e9 b9 ee 47 c7 37 34 80 18 00 b5 81 8f 00 00 01 01 08 0a 88 24 fa c6 32 63 cd 8d
以第一行为例(为16进制数)一位16进制数需要4位2进制数表示,TCP报文一行32位

ip首部

45 00 00 34 //0034为总长度 52

7a 67 40 00

40 06 63 5a

0a cd 0a f4 //源地址 10.205.10.244

7d 38 ca 09 //目的地址 125.56.202.9

tcp首部

cd f6 00 50 //源端口cdf6即52726 目的端口0050即80

b4 d7 ae 1c

9b cf f2 40

80 10 ff 3d

fd d0 00 00

01 01 08 0a

32 53 7d fb

5e 49 4e c8

输出样例

Case #1
Total length = 52 bytes
Source = 10.205.10.244
Destination = 125.56.202.9
Source Port = 52726
Destination Port = 80
 
Case #2
Total length = 198 bytes
Source = 203.208.46.1
Destination = 10.205.10.244
Source Port = 80
Destination Port = 52833

————————————————
题目解析原文链接:https://blog.csdn.net/stone_fall/article/details/88583161

AC代码

#include <bits/stdc++.h>

using namespace std;

int change(char a)
{
	if(a-'0'>=0&&a-'0'<10) return a-'0';//妈的脑残!告诉你了char别写10!!只能写到 9 啊,f******k 
	else return a-'a'+10;
}

int turn(string str)
{
	int answer=0;
	for(int i=0;i<str.size();i++)
	{
		answer=answer*16;
		answer+=change(str[i]);
	}
	return answer;
}

int main()
{
	int T;
	scanf("%d",&T);
	int casenumber=0;
	getchar();
	while(T--)
	{
		vector<string>myvector;
		string str="";
		while(1)
		{
			char c;
			scanf("%c",&c);
			if(c==' ')
			{
				myvector.push_back(str);
				str="";
			}
			else if(c=='\n')
			{
				break;
			}
			else 
			{
				str=str+c;
			}
		}
		myvector.push_back(str);
		printf("Case #%d\n",++casenumber);
		string temp=myvector[2]+myvector[3];
		int answer=turn(temp);
		printf("Total length = %d bytes\n",answer);
		printf("Source = %d.%d.%d.%d\n",turn(myvector[12]),turn(myvector[13]),turn(myvector[14]),turn(myvector[15]));
		printf("Destination = %d.%d.%d.%d\n",turn(myvector[16]),turn(myvector[17]),turn(myvector[18]),turn(myvector[19]));
		string temp2=myvector[20]+myvector[21];
		printf("Source Port = %d\n",turn(temp2));
		string temp3=myvector[22]+myvector[23];
		printf("Destination Port = %d\n",turn(temp3));
		printf("\n"); 
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值