2019寒假训练营第二次作业

学习视频课程(20')

  • 学习福州大学网络课程 网络空间安全概论,形成学习笔记,发布专门博客,至少完成第一章、第四章的视频学习。
  • 或学习密歇根大学的网络课程Internet history,形成学习笔记,另外发布专门的博客。至少完成第一周的视频学习。
  • 以上两门课程二选一即可。

博客地址:https://www.cnblogs.com/fzulinxin/p/10346809.html


程序题(80'+50')

背景

大学期间,你总是点子很多,你利用申请的专利,开了一家互联网公司,为客户提供高效、快捷的服务。有一天,订单量突然大涨,欣喜之余,秘书却告诉你,今天的营业额跌到谷底,客服电话被打爆。你发现,看似很多的订单请求,其实只是给你发了一个“hello”而已,服务器忙于应付大量的hello, 已经没办法给原有用户提供正常的服务了,基本处于瘫痪的状态。经过讨论,可能是受到了黑客的DDos(分布式拒绝服务)攻击。黑客通过发送大量的无用的请求信息,占用你的服务器资源,让服务器没法给用户提供正常的服务。

做法

当务之急,是先恢复服务器,把攻击你的黑客都拉进黑名单,让服务器不要理会这些请求。第一步,就是要把黑客检测出来。你需要对请求进行审查,找出其中有问题的请求,然后把发送方拉黑。这些请求长这个样子:发送方的名字由4个小写英文字母组成,后面跟着接收方和请求信息的大小,你可以通过请求信息的大小推测请求的内容。

表格

你的服务器就是那个可怜的Bob,而发送方有很多,有的是普通用户,而有的就是黑客了。很明显,黑客在短时间给你发了大量的信息,发送方中的 abcd 就很有可能是黑客,因为他在短时间内给你发了很多信息量很小的请求(64,很可能只有hello),而且这些请求值总值已经超过了1500。本着宁错杀一千,不放过一个的原则,只要总的请求信息的大小超过T=1500,就把它拉黑。

描述

编程语言不限


热身题(20')

学习基本的文件读写
读提供的文件Request.txt
把里面的内容写到output.txt

基本题(60')

根据提供请求的输入Request.txt,把所有请求和对应的信息大小都存下来。
统计每个发送方的总请求大小S,S超过T的就认定为黑客,把他们的名字存进你的黑名单里。
输出黑客的个数,和这些黑客的名字。
例如:示例中有28个请求,其中abcd发了25个请求,这些请求的总和S是1600>1500=T,所以abcd被认为是黑客,就把abcd加到你的黑名单里去。

开放题(50')

现在你已经暂时恢复了服务。但你发现,1的方法很笨,例如:把所有请求都存下来,再统计总值,花费了你大量的存储空间。这里面包含了很多不必要的操作,有很多缺点。
吐槽1方法,找到这个方法的问题。给出你的方法,不一定是完美的,说出方法的优缺点,只要能自圆其说。(可以从速度、占用的空间、准确率等方面思考)
选做:实现你的方法。


输入:
名字和信息大小用一个空格隔开,每条信息用一个换行隔开

lhyy bob 100
hzrr bob 700
cyxx bob 364
lhyy bob 700
lhyy bob 800
zzyy bob 300
zzyy bob 800
zzyy bob 600

输出:
第一行输出黑客的总个数,第二行输出黑客名,每个黑客名用一个换行隔开

2
lhyy
zzyy

实现思路:

  • 使用C++中stl库的map,定义map<string, int> request_sum记录每个发送方向服务器提交的总请求大小。
  • 读取所有的请求,加入request_sum中。
  • 遍历request_sum,输出记录值大于T的用户。

思路改进(开放题):

  • 注意到,如果黑客发送的信息总量大于int时会导致程序崩溃
  • 改进策略:1、开大数据范围(治标不治本)2、忽略记录总值大于T的发送请求
  • 因此我们采用方法2,方法2的优势:
    • 减少服务器需要存储的数据,保证每个用户的数据量不大于T
    • 通过动态调整T的大小,减少误杀提高准确度。
    • 避免了大量数据的读取,节省了时间。
  • 第二个问题是,有的虽然只提交了一两次请求但数据量大于T的发送方会被“误杀”,“错杀一千”可能就错过了重要的订单。
  • 改进策略:新建map<string, int> request_max记录每个发送方向服务器提交的最大单次请求大小。
  • 当记录总值大于T且最大单次大小小于M时,忽略该发送请求。减少误杀提高准确度。
  • 缺点:黑客发送一次数据量大等于M的请求,即可绕开后续检测。

实现代码:

#include<bits/stdc++.h>
using namespace std;

const int T=1500;

int main(){
	freopen("Request.txt","r",stdin);
	freopen("output.txt","w",stdout);
	
	map<string, int> request_sum;
	
	string request_name,server_name;
	int request_num,blacklist_size=0;
	
	while (cin>>request_name>>server_name>>request_num)
	{
		if (request_sum[request_name]<=T)
		{
			request_sum[request_name]+=request_num;
			if (request_sum[request_name]>T)
			{
				blacklist_size++;
			}
		}
	}
	
	map<string, int>::iterator it;
	
	printf("%d\n",blacklist_size);
	for (it=request_sum.begin(); it!=request_sum.end(); it++)
	{
		if ((it->second)>T)
		{
			cout<<it->first<<'\n';
		}
	}
	
	fclose(stdin);
	fclose(stdout); 
	return 0;
}

GitHub:https://github.com/Echohat/031802319/tree/master/second

posted @ 2019-01-28 14:59  Synnn  阅读(273)  评论(2编辑  收藏  举报