20212217刘恒谦 实验三《Python程序设计》实验报告

20212217刘恒谦 《Python程序设计》实验三报告

课程:《Python程序设计》
班级: 2122
姓名: 刘恒谦
学号:20212217
实验教师:王志强
实验日期:2022年4月23日
必修/选修: 公选课

代码链接:
服务器
https://gitee.com/besti-cs/modest-warehouse/blob/master/服务器.py

`

# 服务器
import socket as sk

def decipher(D:int, N:int, data:bytes)->int:
	for i in data:
		yield pow(i,D)%N


s = sk.socket(sk.AF_INET, sk.SOCK_STREAM)

s.bind(("", 5050))
s.listen(2)
conn,addr = s.accept()
data = conn.recv(1024)

f = open("C:\Users\Huawei\Desktop\write.txt", "a", encoding="utf-8")
info=bytes(decipher(77,259,data)).decode("utf-8")
f.write(info)
f.close()


print("已接收", info)
s.close()

`

客户端
https://gitee.com/besti-cs/modest-warehouse/blob/master/客户端.py
`

# 客户端
import socket as sk


def encrypt(E: int, N: int, string: str) -> int:
	for i in string.encode("utf-8"):
		yield pow(i, E) % N


HOST = "127.0.0.1"
# 这个是电脑自己的IP,和别人的电脑交流时要改成别人的IP
PORT = 5050
# 这个要和服务器的端口号一致

s = sk.socket(sk.AF_INET, sk.SOCK_STREAM)
s.connect((HOST, PORT))

# 读取文件
f = open("C:\Users\Huawei\Desktop\read.txt", "r", encoding="utf-8")
msg = f.read()
f.close()

# 发送密文
s.sendall(bytes(encrypt(101, 259, msg)))

data = s.recv(1024)
print("已写入", msg)
s.close()

`

1.实验内容

利用socket进行网络通信,并在客户端读取文件,加密传输至服务端,服务端解密并保存。

2. 实验过程及结果

结合知乎上的资料,基本写出了socket制作服务器和客户端的代码。

服务器的代码如下(初级代码,只能在终端你说一句,我说一句)
`

import socket

HOST = ''  #主机
PORT = 5050  #端口
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
	s.bind((HOST, PORT))
	#bind(address), 传输层为AF_INET时address是(主机host,端口port)格式
	s.listen(2)
	conn, addr = s.accept()
	#conn新的套接字对象,用于接收发送数据,
	# addr客户端地址为元组(hostname, port)

	with conn:  #while里面只能有recieve和send
		print('Connected by', addr)
		while True:  #server先接收再发送
			data = conn.recv(1024)
			print(f"{addr}说:{data.decode()}")
			server_msg=input("请输入你想回复的内容,输入exit则退出:n")
			conn.sendall(server_msg.encode())
			if server_msg=="exit":
				break

`
作为服务器,首先要能够一直等待来响应用户的请求,因此有了listen方法,它接受监听的最大用户数量,在Python中最多设置5个。如果监听到,那么它就会返回客户对象conn,以及它的IP地址。这个IP地址我们目前还用不着。而用户conn却有很大的用处,在这里我们设置一个监听用户的循环,直到服务器发出exit命令我们才退出。

客户端的代码如下(初级代码,只能在终端你说一句,我说一句)
`

# client.py
import socket

# HOST = 'localhost'

HOST = '192.168.10.191'
PORT = 5050

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
	s.connect((HOST, PORT))
	while True:  #while里面只能有send和recieve
		msg=input("请输入你想传达的信息,传入exit则退出n")
		if msg=="exit":
			break

# client先发送消息再接收
		s.sendall(msg.encode())
		data = s.recv(1024)
		print(f"他说 {data.decode()}")

`
客户端和服务器类似,只不过不用listen。其他部分都是大同小异的。

3. 实验过程中遇到的问题和解决过程

-RSA加密算法

上网查资料,了解到现代加密算法基本包括RSA,Hash,等算法,其中可解密的加密称双向加密。利用这个关键词,我又去网上查阅了大量资料,决定采用RSA加密算法。它赫赫有名,广为流行,使用较多,算法简单,解密困难。

  • 基本思路如下:
    不同数据
    可以用同样的字符排列组合来代表

    加密和解密只需要改变这个字符

  • RSA解密算法
    N为字符总量,如果有一个D
    (密文**D)%N=明文。
    (D,N)称为私钥

  • 加密算法
    如果还有个E
    (明文**E)%N=密文
    (E,N)称为公钥

  • D和E的制作
    选取2个质数:p=3; q=11
    质数相乘:N=p*q=33
    计算欧拉函数 T=(p-1)(q-1)=20
    选取公钥 1st.E是质数;2nd.1<E<T;3st.E不是T的因数
    计算私钥 (D *E)%T=1

字符串与字节串

在Python2中,字符以字节的形式在程序里运行。但在Python3之后,字符的编码变复杂了,出现了不同于于Python2的字符串,复杂的字符和简单的字符用着同一套字节却有着不同的编码规则。
Python3中,在字符的""前加b(表示binary二进制)即可表示字节串。
bytes_string=b'xe4xbax94xe4xb8x80xe5x8axb3xe5x8axa8xe8x8ax82xe5xbfxabxe4xb9x90'

在网络传输过程中,为了保证字符能够被正确解读,要求发送方和接受方都必须知道传输过程中字符的编码。如果简单的字符和复杂的字符有不同的规则,那么传输的每一个字都必须标注它的编码格式,极大地占用了传输资源。因此,整个文件要有统一的编码标准,传输过程中要将字符串还原成字节串。

  • 那么,怎么将str变成bytes呢,很简单,调用encode编码方法即可。
    image
    输出如下
    image

字符的数字化不仅使其能在计算机中方便传输,同时也为加密和解密提供了新思路。
本代码中,读取的是明文,写入的是明文。但是发送、传输、接受都用的是密文。我们可以将字符数字化,之后再将其加密,解密。

  • 那么怎么将数字变回字符呢?
    用decode(解码)方法即可
    image

  • 用一张图来表示string和bytes的关系。
    image
    图片来源于CSDN,原文链接https://blog.csdn.net/beyondlee2011/article/details/86159151

其他(感悟、思考等)

密码是门大学问,学习密码要有深厚的数学基础。当然落实到计算机上,代码功底也必不可少。

参考资料

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:20212217刘恒谦 实验三《Python程序设计》实验报告 - Python技术站

(0)
上一篇 2023年4月2日
下一篇 2023年4月2日
合作推广
合作推广
分享本页
返回顶部