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

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

服务器
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()
客户端
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制作服务器和客户端的代码。

服务器的代码如下(初级代码,只能在终端你说一句,我说一句)
</p> <pre><code>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 </code></pre> <p>
作为服务器,首先要能够一直等待来响应用户的请求,因此有了listen方法,它接受监听的最大用户数量,在Python中最多设置5个。如果监听到,那么它就会返回客户对象conn,以及它的IP地址。这个IP地址我们目前还用不着。而用户conn却有很大的用处,在这里我们设置一个监听用户的循环,直到服务器发出exit命令我们才退出。

客户端的代码如下(初级代码,只能在终端你说一句,我说一句)
</p> <pre><code>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()}") </code></pre> <p>
客户端和服务器类似,只不过不用listen。其他部分都是大同小异的。

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

上网查资料,了解到现代加密算法基本包括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

在Python2中,字符以字节的形式在程序里运行。但在Python3之后,字符的编码变复杂了,出现了不同于于Python2的字符串,复杂的字符和简单的字符用着同一套字节却有着不同的编码规则。
Python3中,在字符的””前加b(表示binary二进制)即可表示字节串。
bytes_string=b'\xe4\xba\x94\xe4\xb8\x80\xe5\x8a\xb3\xe5\x8a\xa8\xe8\x8a\x82\xe5\xbf\xab\xe4\xb9\x90'

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

  • 那么,怎么将str变成bytes呢,很简单,调用encode编码方法即可。
    20212217刘恒谦 实验三《Python程序设计》实验报告
    输出如下
    20212217刘恒谦 实验三《Python程序设计》实验报告

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

  • 那么怎么将数字变回字符呢?
    用decode(解码)方法即可
    20212217刘恒谦 实验三《Python程序设计》实验报告
  • 用一张图来表示string和bytes的关系。
    20212217刘恒谦 实验三《Python程序设计》实验报告
    图片来源于CSDN,原文链接https://blog.csdn.net/beyondlee2011/article/details/86159151

其他(感悟、思考等)

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

参考资料

Original: https://www.cnblogs.com/cyber-explorer/p/socket-test.html
Author: 谦寻大川
Title: 20212217刘恒谦 实验三《Python程序设计》实验报告

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/713341/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球