基于OpenSSL的安全Web Server实现

news2024/12/29 10:27:13

目录

一、实验目的

二、实验软硬件要求

三、实验预习

四、实验内容(实验步骤、测试数据等)

实验步骤

1编辑代码

2解决报错

3准备网页

五、实验体会(遇到的问题及解决方法)

六、服务器代码

七、测试网页代码


一、实验目的

熟悉软件安全需求分析方法,掌握软件安全分析技术。

二、实验软硬件要求

1、操作系统:windows 7/8/10等

2、安装OpenSSL-win64

3、安装VS2019

三、实验预习

《软件安全技术》教材第8章

四、实验内容(实验步骤、测试数据等)

1. 目标:完成基于OpenSSL的安全Web Server实现,要求:

(1)在理解HTTPS及SSL工作原理的基础上,实现安全的Web Server。

(2)Server能够并发处理多个请求,要求至少能支持Get命令。可以增加Web Server的功能,如支持Head、Post及Delete命令等;

(3)编写必要的客户端测试程序,用户发送HTTPS请求并返回结果,也可以使用一般的浏览器程序。

2. 步骤:

(1) 在VS 上实现服务端、客户端程序;

(2) 功能测试。

3、实验报告。

实验步骤

1编辑代码

2解决报错

文件会报sscanf的错误

VS2019:严重性代码说明项目文件行禁止显示状态错误C4996:‘scanf‘: This function or variable may be unsafe

在项目-属性-C/C++这边,选择SDL检查否。

3准备网页

3-1编辑网页

3-2将文件放在代码里面的路径上

4测试结果

在编写的网页上,上传图片,测试Server是否能够成功处理命令

注意url输入是http://127.0.0.1/WebServer1.0/index.html

点击上传图片

无法检测到这个上传动作

进行刷新,可以检测到重连的动作

五、实验体会(遇到的问题及解决方法)

实验遇到一些代码函数与编译器不匹配的问题,通过搜索进行解决。实验依旧遇到了一些没法解决的问题,例如网页上传图片,负责监测的ooo.exe无法进行检测,只能检测到get,不能检测到put。需要后面的时间里,再进行分析解决。

六、服务器代码

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNNINGS

#define SERVER_IP_ADDR "127.0.0.1"	//服务器IP地址
#define SERVER_PORT 80				//服务器端口号
#define BACKLOG 10
#define BUF_SIZE 1024
#define OK 1
#define ERROR 0

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h> 
#include <time.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")

const char* Server_name = "Server: Web Server 1.0 - BooLo\r\n";
//Web服务器信息 

int Server_Socket_Init();
int Handle_Request_Message(char* message, int Socket);
int Judge_URI(char* URI, int Socket);
int Send_Ifon(int Socket, const char* sendbuf, int Length);
int Error_Request_Method(int Socket);
int Inquire_File(char* URI);
int File_not_Inquire(int Socket);
int Send_File(char* URI, int Socket);
int Logo();
const char* Judge_Method(char* method, int Socket);
const char* Judge_File_Type(char* URI, const char* content_type);
const char* Get_Data(const char* cur_time);
const char* Post_Value(char* message);

int Server_Socket_Init() {
	//初始化和构造套接字 
	WORD wVersionrequested;
	WSADATA wsaData;
	SOCKET ServerSock;
	struct sockaddr_in ServerAddr;
	int rval;

	/* 加载Winsock */
	wVersionrequested = MAKEWORD(2, 2);
	if (WSAStartup(wVersionrequested, &wsaData) != 0) {
		printf("Failed to load Winsock!\n");
		system("pause");
		return -1;
	}
	printf("Succeed to load Winsock!\n");

	/* 创建套接字 */
	ServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (ServerSock == INVALID_SOCKET) {
		printf("Failed to create socket!\n");
		system("pause");
		exit(1);
	}
	printf("Succeed to create socket!\n");

	/* 配置服务器IP、端口信息 */
	memset(&ServerAddr, 0, sizeof(struct sockaddr));	//每一个字节都用0来填充
	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(SERVER_PORT);
	ServerAddr.sin_addr.s_addr = inet_addr(SERVER_IP_ADDR);

	/* 绑定 */
	rval = bind(ServerSock, (SOCKADDR*)&ServerAddr, sizeof(struct sockaddr));
	if (rval == SOCKET_ERROR) {
		printf("Failed to bind stream socket!\n");
		system("pause");
		exit(1);
	}
	printf("Succeed to bind stream socket!\n");

	return ServerSock;
}

int Handle_Request_Message(char* message, int Socket) {
	//处理HTTP请求报文信息 
	int rval = 0;
	char Method[BUF_SIZE];
	char URI[BUF_SIZE];
	char Version[BUF_SIZE];

	if (sscanf(message, "%s %s %s", Method, URI, Version) != 3) {
		printf("Request line error!\n");
		return ERROR;
	}	//提取"请求方法"、"URL"、"HTTP版本"三个关键要素 

	if (Judge_Method(Method, Socket) == ERROR) {
		return ERROR;
	}
	else if (Judge_Method(Method, Socket) == "POST") {
		Post_Value(message);
	}	//判断处理"请求方法" 

	if (Judge_URI(URI, Socket) == ERROR) {
		return ERROR;
	}	//判断处理"URI" 
	else
		rval = Send_File(URI, Socket);

	if (rval == OK) {
		printf("The process is successfully finished!\n");
	}

	return OK;
}

const char* Judge_Method(char* method, int Socket) {
	//判断请求方式 
	if (strcmp(method, "GET") == 0) {
		return "GET";
	}
	else if (strcmp(method, "POST") == 0) {
		return "POST";
	}
	else {
		Error_Request_Method(Socket);
		return ERROR;
	}
}

int Judge_URI(char* URI, int Socket) {
	//判断请求URI 
	if (Inquire_File(URI) == ERROR) {
		File_not_Inquire(Socket);
		return ERROR;
	}
	else
		return OK;
}

int Send_Ifon(int Socket, const char* sendbuf, int Length) {
	//发送信息到客户端 
	int sendtotal = 0, bufleft, rval = 0;

	bufleft = Length;
	while (sendtotal < Length) {
		rval = send(Socket, sendbuf + sendtotal, bufleft, 0);
		if (rval < 0) {
			break;
		}
		sendtotal += rval;
		bufleft -= rval;
	}

	Length = sendtotal;

	return rval < 0 ? ERROR : OK;
}

int Error_Request_Method(int Socket) {
	//501 Not Implemented响应 
	const char* Method_err_line = "HTTP/1.1 501 Not Implemented\r\n";
	const char* cur_time = "";
	const char* Method_err_type = "Content-type: text/plain\r\n";
	const char* File_err_length = "Content-Length: 41\r\n";
	const char* Method_err_end = "\r\n";
	const char* Method_err_info = "The request method is not yet completed!\n";

	printf("The request method from client's request message is not yet completed!\n");

	if (Send_Ifon(Socket, Method_err_line, strlen(Method_err_line)) == ERROR) {
		printf("Sending method_error_line failed!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, Server_name, strlen(Server_name)) == ERROR) {
		printf("Sending Server_name failed!\n");
		return ERROR;
	}

	cur_time = Get_Data(cur_time);
	Send_Ifon(Socket, "Data: ", 6);
	if (Send_Ifon(Socket, cur_time, strlen(cur_time)) == ERROR) {
		printf("Sending cur_time error!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, Method_err_type, strlen(Method_err_type)) == ERROR) {
		printf("Sending method_error_type failed!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, Method_err_end, strlen(Method_err_end)) == ERROR) {
		printf("Sending method_error_end failed!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, Method_err_info, strlen(Method_err_info)) == ERROR) {
		printf("Sending method_error_info failed!\n");
		return ERROR;
	}

	return OK;
}

int Inquire_File(char* URI) {
	//查找文件 
	struct stat File_info;

	if (stat(URI, &File_info) == -1)
		return ERROR;
	else
		return File_info.st_size;
}

int File_not_Inquire(int Socket) {
	//404 Not Found响应 
	const char* File_err_line = "HTTP/1.1 404 Not Found\r\n";
	const char* cur_time = "";
	const char* File_err_type = "Content-type: text/plain\r\n";
	const char* File_err_length = "Content-Length: 42\r\n";
	const char* File_err_end = "\r\n";
	const char* File_err_info = "The file which is requested is not found!\n";

	printf("The request file from client's request message is not found!\n");

	if (Send_Ifon(Socket, File_err_line, strlen(File_err_line)) == ERROR) {
		printf("Sending file_error_line error!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, Server_name, strlen(Server_name)) == ERROR) {
		printf("Sending Server_name failed!\n");
		return ERROR;
	}

	cur_time = Get_Data(cur_time);
	Send_Ifon(Socket, "Data: ", 6);
	if (Send_Ifon(Socket, cur_time, strlen(cur_time)) == ERROR) {
		printf("Sending cur_time error!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, File_err_type, strlen(File_err_type)) == ERROR) {
		printf("Sending file_error_type error!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, File_err_length, strlen(File_err_length)) == ERROR) {
		printf("Sending file_error_length error!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, File_err_end, strlen(File_err_end)) == ERROR) {
		printf("Sending file_error_end error!\n");
		return ERROR;
	}

	if (Send_Ifon(Socket, File_err_info, strlen(File_err_info)) == ERROR) {
		printf("Sending file_error_info failed!\n");
		return ERROR;
	}

	return OK;
}

int Send_File(char* URI, int Socket) {
	//200 OK响应 
	const char* File_ok_line = "HTTP/1.1 200 OK\r\n";
	const char* cur_time = "";
	const char* File_ok_type = "";
	const char* File_ok_length = "Content-Length: ";
	const char* File_ok_end = "\r\n";

	FILE* file;
	struct stat file_stat;
	char Length[BUF_SIZE];
	char sendbuf[BUF_SIZE];
	int send_length;

	if (Judge_File_Type(URI, File_ok_type) == ERROR) {
		printf("The request file's type from client's request message is error!\n");
		return ERROR;
	}

	file = fopen(URI, "rb");
	if (file != NULL) {
		fstat(fileno(file), &file_stat);
		itoa(file_stat.st_size, Length, 10);

		if (Send_Ifon(Socket, File_ok_line, strlen(File_ok_line)) == ERROR) {
			printf("Sending file_ok_line error!\n");
			return ERROR;
		}

		if (Send_Ifon(Socket, Server_name, strlen(Server_name)) == ERROR) {
			printf("Sending Server_name failed!\n");
			return ERROR;
		}

		cur_time = Get_Data(cur_time);
		Send_Ifon(Socket, "Data: ", 6);
		if (Send_Ifon(Socket, cur_time, strlen(cur_time)) == ERROR) {
			printf("Sending cur_time error!\n");
			return ERROR;
		}

		File_ok_type = Judge_File_Type(URI, File_ok_type);
		if (Send_Ifon(Socket, File_ok_type, strlen(File_ok_type)) == ERROR) {
			printf("Sending file_ok_type error!\n");
			return ERROR;
		}

		if (Send_Ifon(Socket, File_ok_length, strlen(File_ok_length)) != ERROR) {
			if (Send_Ifon(Socket, Length, strlen(Length)) != ERROR) {
				if (Send_Ifon(Socket, "\n", 1) == ERROR) {
					printf("Sending file_ok_length error!\n");
					return ERROR;
				}
			}
		}

		if (Send_Ifon(Socket, File_ok_end, strlen(File_ok_end)) == ERROR) {
			printf("Sending file_ok_end error!\n");
			return ERROR;
		}

		while (file_stat.st_size > 0) {
			if (file_stat.st_size < 1024) {
				send_length = fread(sendbuf, 1, file_stat.st_size, file);
				if (Send_Ifon(Socket, sendbuf, send_length) == ERROR) {
					printf("Sending file information error!\n");
					continue;
				}
				file_stat.st_size = 0;
			}
			else {
				send_length = fread(sendbuf, 1, 1024, file);
				if (Send_Ifon(Socket, sendbuf, send_length) == ERROR) {
					printf("Sending file information error!\n");
					continue;
				}
				file_stat.st_size -= 1024;
			}
		}
	}
	else {
		printf("The file is NULL!\n");
		return ERROR;
	}

	return OK;
}

const char* Judge_File_Type(char* URI, const char* content_type) {
	//文件类型判断 
	const char* suffix;

	if ((suffix = strrchr(URI, '.')) != NULL)
		suffix = suffix + 1;

	if (strcmp(suffix, "html") == 0) {
		return content_type = "Content-type: text/html\r\n";
	}
	else if (strcmp(suffix, "jpg") == 0) {
		return content_type = "Content-type: image/jpg\r\n";
	}
	else if (strcmp(suffix, "png") == 0) {
		return content_type = "Content-type: image/png\r\n";
	}
	else if (strcmp(suffix, "gif") == 0) {
		return content_type = "Content-type: image/gif\r\n";
	}
	else if (strcmp(suffix, "txt") == 0) {
		return content_type = "Content-type: text/plain\r\n";
	}
	else if (strcmp(suffix, "xml") == 0) {
		return content_type = "Content-type: text/xml\r\n";
	}
	else if (strcmp(suffix, "rtf") == 0) {
		return content_type = "Content-type: text/rtf\r\n";
	}
	else
		return ERROR;
}

const char* Get_Data(const char* cur_time) {
	//获取Web服务器的当前时间作为响应时间 
	time_t curtime;
	time(&curtime);
	cur_time = ctime(&curtime);

	return cur_time;
}

const char* Post_Value(char* message) {
	//获取客户端POST请求方式的值 
	const char* suffix;

	if ((suffix = strrchr(message, '\n')) != NULL)
		suffix = suffix + 1;
	printf("\n\nPost Value: %s\n\n", suffix);

	return suffix;
}

int Logo() {
	//Web服务器标志信息 
	printf("___________________________________________________________\n");
	printf("  __          ________ _______\n");
	printf("  \\ \\        / /  ____|  _____\\\n");
	printf("   \\ \\  /\\  / /| |____  |____) )\n");
	printf("    \\ \\/  \\/ / |  ____|  ____(   __  __     __ ___\n");
	printf("     \\  /\\  /  | |____  |____) )(__ |_ \\  /|_ |___)\n");
	printf("      \\/  \\/   |______|_______/  __)|__ \\/ |__|   \\\n");
	printf("\n");
	printf("            Welcome to use the Web Server!\n");
	printf("                     Version 1.0\n\n");
	printf("                         BooLo\n");
	printf("___________________________________________________________\n\n");

	return OK;
}

int main() {
	//实现主要功能 
	SOCKET ServerSock, MessageSock;
	struct sockaddr_in ClientAddr;
	int rval, Length;
	char revbuf[BUF_SIZE];

	Logo();
	printf("Web Server 1.0 is starting......\n\n");
	ServerSock = Server_Socket_Init();
	printf("\n-----------------------------------------------------------\n");

	while (OK) {
		/* 启动监听 */
		rval = listen(ServerSock, BACKLOG);
		if (rval == SOCKET_ERROR) {
			printf("Failed to listen socket!\n");
			system("pause");
			exit(1);
		}
		printf("Listening the socket ......\n");

		/* 接受客户端请求建立连接 */
		Length = sizeof(struct sockaddr);
		MessageSock = accept(ServerSock, (SOCKADDR*)&ClientAddr, &Length);
		if (MessageSock == INVALID_SOCKET) {
			printf("Failed to accept connection from client!\n");
			system("pause");
			exit(1);
		}
		printf("Succeed to accept connection from [%s:%d] !\n\n", inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port));

		/* 接收客户端请求数据 */
		memset(revbuf, 0, BUF_SIZE);	//每一个字节都用0来填充 
		rval = recv(MessageSock, revbuf, BUF_SIZE, 0);
		revbuf[rval] = 0x00;
		if (rval <= 0)
			printf("Failed to receive request message from client!\n");
		else {
			printf("%s\n", revbuf);	//输出请求数据内容
			rval = Handle_Request_Message(revbuf, MessageSock);
		}

		closesocket(MessageSock);
		printf("\n-----------------------------------------------------------\n");
	}

	closesocket(ServerSock);	//关闭套接字 
	WSACleanup();	//停止Winsock

	return OK;
}

七、测试网页代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>软件安全OpenSSL测试上传</title>
</head>
<body>
    <h1>CF上传图片测试
    <h2>仅仅只能上传图片而已
    <div class="upload">
        <img src="" alt="" style="width: 200px;height:200px;background:red;">
        <button>点击上传</button>
        <input type="file" style="display:none" class="fileDoms" onchange="changeFile()"/>
    </div>
</body>
<script>
    let btn  = document.querySelector(".upload button")
    let img = document.querySelector(".upload img")
    const fileInputs = document.querySelector('.fileDoms')
    btn.onclick = btnclick
    function btnclick(){
        fileInputs.click()
    }
    function changeFile(){
        console.log("上传")
        let reader = new FileReader();
        reader.readAsDataURL(fileInputs.files[0]);
        reader.onload = function(a){
            img.src = a.target.result; //等同于reader.result
            console.log(a,reader,reader.result);
        }
    }
    </script>
</html>

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

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

相关文章

(02)Cartographer源码无死角解析-(43) 2D栅格地图→

讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解(02)Cartographer源码无死角解析-链接如下: (02)Cartographer源码无死角解析- (00)目录_最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/127350885 文末…

利用Python构建Wiki中文语料词向量模型

利用Python构建Wiki中文语料词向量模型试验 完整代码下载地址&#xff1a;利用Python构建Wiki中文语料词向量模型 本实例主要介绍的是选取wiki中文语料&#xff0c;并使用python完成Word2vec模型构建的实践过程&#xff0c;不包含原理部分&#xff0c;旨在一步一步的了解自然语…

CH450/TM1637 驱动调试

CH450&#xff1a;支持带有中断的扫描键盘、数码显示&#xff1b; TM1637&#xff1a;键盘扫描/数码显示&#xff1b; CH450/TM1637 I2C的时序调试有问题&#xff0c;总体上注意以下几点 MSB还是LSB&#xff0c;这两个不一样&#xff1b;&#xff08;TM1637从低到高传输&…

PhpStorm 使用全局搜索得不到结果

一、前言二、解决一、前言 全文搜索快捷键&#xff1a;ctrl shift f&#xff0c;如果 没有弹出搜索框。看下快捷键是不是被其他软件占用了&#xff1a;比如搜狗输入法现在的问题是&#xff1a;输入想要搜索的关键字&#xff0c;但是没用搜出来结果&#xff08;实际上关键字在…

BurpSuite与Xray联动进行被动扫描实战

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是BurpSuite与Xray联动进行被动扫描实战。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#xff01; 再次强调&#xf…

Linux权限及其理解

文章目录&#xff1a;Linux权限的概念Linux权限管理文件访问者的分类&#xff08;人&#xff09;文件类型和访问权限&#xff08;事物属性&#xff09;文件权限值的表示方法文件访问权限的设置方法权限掩码目录的权限粘滞位总结Linux权限的概念 与其它系统相比&#xff0c;Lin…

文件包含漏洞渗透与攻防(一)

目录 前言 什么是文件包含漏洞 文件包含漏洞类型 本地文件包含 远程文件包含 PHP相关函数和伪协议 函数 PHP伪协议 CTF题目案例 文件包含漏洞挖掘与利用 URL关键字 代码审计 利用流程 文件包含漏洞修复方案 前言 随着网站业务的需求&#xff0c;程序开发人员一…

【ACWING】【图的广度遍历】【848有向图的拓扑顺序】

给定一个 n个点 m条边的有向图&#xff0c;点的编号是 1到 n&#xff0c;图中可能存在重边和自环。 请输出任意一个该有向图的拓扑序列&#xff0c;如果拓扑序列不存在&#xff0c;则输出 −1。 若一个由图中所有点构成的序列 A满足&#xff1a;对于图中的每条边 (x,y)&#…

STM32MP157驱动开发——Linux CAN驱动

STM32MP157驱动开发——Linux CAN驱动一、简介1.电气属性2.CAN协议3.CAN速率4.CAN FD 简介二、驱动开发1.修改设备树2.FDCAN1控制器节点3.修复 m_can_platform.c4.使能 CAN 总线5.使能FDCAN外设驱动三、运行测试1.移植 iproute2 和 can-utils 工具2.测试1&#xff09;收发测试&…

数据结构排序

文章目录直接插入排序直接插入排序 核心代码 void InsertSort(int arr[], int n) {for (int i 2; i < n; i) ///直接从第二个元素开始遍历{if (arr[i - 1] > arr[i]) //判断前一个元素和当前元素的大小&#xff0c;若前一个元素小于当前元素才需要插入{arr[0] …

Markdown之折叠语法以及表格内父子折叠

背景 在编写接口文档的时候发现一些特别扭的问题&#xff0c;就是一个表格来说明入参和出参的时候&#xff0c;怎么去表达嵌套的父子关系呢&#xff1f;查看了大厂的接口文档&#xff0c;比如微信支付&#xff0c;他们是有完善的接口文档页面&#xff0c;也都全部标记出了表格…

pycharm-qt5-基础篇1

pycharm-qt5-基础篇1一: QT5介绍1> 主要的特性2> pycharm 外部工具及功能1. Qt Designer2. PyUic3> PyUrcc二: pycharm QT5 环境搭建1> 虚拟环境搭建2> 安装 pyqt5、pyqt5-tools3> 将QT工具添加到环境变量4> 配置PyCharm三: QT5 demo四: pyinstaller 打包…

Java 并发编程知识总结【三】

4. CompletableFuture 4.1 Future 和 Callable 接口 Future 接口定义了操作异步任务执行一些方法&#xff0c;如获取异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕等。 Callable 接口中定义了需要有返回的任务需要实现的方法。 使用途径&am…

详解Spring面试AOP

文章目录什么是 AOP&#xff1f;AOP作用AOP核心概念&#xff08;来自黑马程序课程&#xff09;AOP 解决了什么问题&#xff1f;AOP 为什么叫做切面编程&#xff1f;总结1 AOP的核心概念2 切入点表达式3 五种通知类型4 通知中获取参数AOP是面向切面编程&#xff0c;是一个设计思…

Java同学录系统同学录网站

简介 用户注册可以创建班级&#xff08;创建者即为群主&#xff09;&#xff0c;用户也可以查找班级申请加入&#xff0c;群主添加同学的联系方式等&#xff0c;可以在班级里留言&#xff0c;管理相册等&#xff0c;还可以指定其他人为群主或者解散班级群&#xff0c;群里的用…

【ROS】—— ROS快速上手(一)

文章目录前言1. ROS-melodic 安装2. ROS基本操作2.1 创建工作空间2.2 创建功能包2.3 HelloWorld(C版)2.4 HelloWorld(Python版)3. Vscode ROS 插件4. vscode 使用基本配置4.1 启动 vscode4.2 vscode 中编译 ros5. launch文件演示6. ROS文件系统7. ROS文件系统相关命令前言 &…

EMNLP22评测矩阵:FineD-Eval: Fine-grained Automatic Dialogue-Level Evaluation

总结 在选择维度时&#xff0c;有点意思。 FineD-Eval: Fine-grained Automatic Dialogue-Level Evaluation 一般对话生成任务的评测也是从多个维度出发&#xff0c;这篇文章先选择了几个相关性程度低的维度&#xff0c;然后&#xff0c;在挑选后的维度上&#xff0c;测评相…

动态规划经典题:编辑距离(hard) 详解,看了还不会你来砍我

&#x1f9f8;&#x1f9f8;&#x1f9f8;各位大佬大家好&#xff0c;我是猪皮兄弟&#x1f9f8;&#x1f9f8;&#x1f9f8; 文章目录一、最长公共子序列二、两个字符串的删除操作三、编辑距离Hard为了更好的理解&#xff0c;我们从易到难的来解决编辑距离的问题一、最长公共…

Tic-Tac-Toe可能棋局遍历的实现(python)

目录 1. 前言 2. 算法流程 3. 代码实现 4. 一个思考题&#xff1a;代码实现中的一个坑 5. 结果正确吗&#xff1f; 1. 前言 在上一篇博客中&#xff1a;Tic-Tac-Toe可能棋局搜索的实现&#xff08;python&#xff09;_笨牛慢耕的博客-CSDN博客Tic-Tac-Toe中文常译作井字棋…

基础数学(五)——数值积分

文章目录考试要求基础概念代数精度&#xff08;必考题&#xff09;代数精度的定义求代数精度的例题&#xff08;期末考试数值积分第一个大题&#xff09;数值积分公式的构造插值型求积公式&#xff08;必考题&#xff09;插值型数值积分公式定理Newton-Cotes求积公式Cotes公式代…