0814Python总结-socketserver,hashlib校验,tcp登录,服务端的合法性校验,

一.socketserver(实现tcp协议server端的并发)

1.server

# ### 服务端
import socketserver

class MyServer(socketserver.BaseRequestHandler):
	def handle(self):
		print("handle方法被执行了...")

# ThreadingTCPServer(ip端口号,自定义的类)
server = socketserver.ThreadingTCPServer(("127.0.0.1", 9000), MyServer)
# 建立连接,循环调用
server.serve_forever()

1.client

# ### 客户端
import socket
sk = socket.socket()
sk.connect(("127.0.0.1", 9000))
# 处理收发数据的逻辑

sk.close()

2.server

# ### 服务端
import socketserver

class MyServer(socketserver.BaseRequestHandler):
	def handle(self):
		"""
		print(self.request)
		print(self.client_address)
		self.request <==> conn
		<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 49116)>
		self.client_address <==> addr ('127.0.0.1', 49116)
		"""

		conn = self.request
		while True:
			# 接收数据
			msg = conn.recv(1024)
			msg2 = msg.decode()
			print(msg2)
			conn.send(msg2.upper().encode())

		print("handle方法被执行了...")

# ThreadingTCPServer(ip端口号,自定义的类)
server =socketserver.ThreadingTCPServer(("127.0.0.1", 9000), MyServer)
# 建立连接,循环调用
server.serve_forever()

2.client

# ### 客户端
import socket
sk = socket.socket()
sk.connect(("127.0.0.1", 9000))
# 处理收发数据的逻辑
while True:
	sk.send(b"you can you up no can no bb")
	msg = sk.recv(1024)
	print(msg.decode())
sk.close()

二.hashlib校验

1.hashlib
import hashlib
import random

1.基本语法

# (1)创建一个md5算法的对象
hm = hashlib.md5()
# (2)把要加密的字符串通过update更新到hm这个对象中运算
hm.update("123456".encode())  # 里面的数据必须是二进制字节流
# (3)获取32位16进制字符串
res = hm.hexdigest()
print(res, len(res))  # e10adc3949ba59abbe56e057f20f883e 32

2.加盐(加key => Xboy_) 加一个关键字配合原字符进行加密,使密码更复杂,不容易被破解

hm = hashlib.md5("Xboy_wangwen".encode())
hm.update("123456".encode())
res = hm.hexdigest()
print(res, len(res))  # fd5cb7cf5fe9f26d1fa2e98eb15a0f19 32

3.动态加盐

res = str(random.randrange(100000, 1000000))
print(res)
hm = hashlib.md5(res.encode())
hm.update("123456".encode())
res = hm.hexdigest()
print(res)
2.sha算法

sha 算出来的十六进制是40位,加密稍慢,安全性稍高
md5 算出来的十六进制是32位,加密很快,安全性稍差

hs = hashlib.sha1()
hs.update("我最是牛逼的&#*($&*(#&%*(&%*&%(#%&".encode())
res = hs.hexdigest()
print(res, len(res))  # 31673dd65f81fddaae07b4240cbb04af047b7496 40
hs = hashlib.sha512()
hs.update("123456".encode())
res = hs.hexdigest()
print(res, len(res))  # ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
3.hmac

hmac 加密算法更加复杂,不容易破解

import hmac

hmac.new(盐,密码)

key = b"a"
msg = b"123456"
hn = hmac.new(key, msg)
res = hn.hexdigest()
print(res, len(res))  # 32为长度 十六进制的字符串  # 3e391a1d7bf574cec59679244a2904fe 32

动态加盐

扫描二维码关注公众号,回复: 11934629 查看本文章
os.urandom 返回随机的二进制字节流
res = os.urandom(32)
print(res, len(res))
key = os.urandom(32)
msg = b"123"
hn = hmac.new(key, msg)
res = hn.hexdigest()
print(res, len(res))

三.文件校验

import hashlib
import os

mode => r read(数字->字符个数)
mode => rb read(数字->字节个数)
字节的个数 <=> 文件的大小

1.针对于小文件进行内容校验
def check_md5(filename):
	hs = hashlib.md5()
	with open(filename, mode="rb") as fp:
		hs.update(fp.read())
	return hs.hexdigest()

res1 = check_md5("ceshi1.txt")
res2 = check_md5("ceshi2.txt")
print(res1, res2)  # 16db316047b59a6c799b0bbf419bf3f4 16db316047b59a6c799b0bbf419bf3f4
2.针对于大文件进行内容校验

可以通过update把字符串分段进行加密

常规方法

strvar = "今天是星期五,好开心了,下周一又要考试了."
hm = hashlib.md5()
hm.update(strvar.encode())
res = hm.hexdigest()
print(res)  # 99b6be31d6ed3bfc7c876c16b7f48ebf

分段更新加密

hm = hashlib.md5()
hm.update("今天是星期五,好开心了,".encode())
hm.update("下周一又要考试了.".encode())
res = hm.hexdigest()
print(res)  # 99b6be31d6ed3bfc7c876c16b7f48ebf
# 方法一
def check_md5(filename):
	hs = hashlib.md5()
	with open(filename, mode="rb") as fp:
		while True:
			content = fp.read(10)  # 一次最多读取10个字节
			if content:
				# 分批进行字符串密码更新
				hs.update(content)
			else:
				break
		return hs.hexdigest()

res1 = check_md5("ceshi1.txt")
res2 = check_md5("ceshi2.txt")
print(res1, res2)  # 16db316047b59a6c799b0bbf419bf3f4 16db316047b59a6c799b0bbf419bf3f4
# 方法二
def check_md5(filename):
	hs = hashlib.md5()
	# 计算文件大小=>返回字节数
	filesize = os.path.getsize(filename)
	with open(filename, mode="rb") as fp:
		while filesize:
			content = fp.read(10)  # 一次最多读取10个字节
			hs.update(content)
			# 按照实际的字节个数读取
			filesize -= len(content)

		return hs.hexdigest()

res1 = check_md5("ceshi1.txt")
res2 = check_md5("ceshi2.txt")
print(res1, res2)  # 16db316047b59a6c799b0bbf419bf3f4 16db316047b59a6c799b0bbf419bf3f4

四.服务端的合法性校验

1.client

# ### 服务端1(公司)
import socket
import hmac

def auth(sk, secret_key):
	# 处理收发数据的逻辑
	msg = sk.recv(32)
	hn = hmac.new(secret_key.encode(), msg)
	res = hn.hexdigest()
	# 把客户端加密的字符串发送给服务端进行验证
	sk.send(res.encode())

sk = socket.socket()
sk.connect(("127.0.0.1", 9000))

# 处理收发数据的逻辑
secret_key = "芝麻开门123"
auth(sk, secret_key)

# 验证成功之后,接收服务端给我的验证码
res = sk.recv(1024).decode()
print(res)

sk.close()

1.server

# ### 服务端2(支付宝)
import socket
import os
import hmac

def auth(conn, secret_key):
	# 随机产生32位的二进制字节流
	msg = os.urandom(32)
	conn.send(msg)
	hn = hmac.new(secret_key.encode(), msg)
	res_server = hn.hexdigest()
	print(res_server)
	# 服务端接收客户端发送过来的数据进行验证
	res_client = conn.recv(1024).decode()

	if res_client == res_server:
		print("你是合法的服务端用户")
		return True
	else:
		print("不是合法的服务端用户")
		return False

sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sk.bind(("127.0.0.1", 9000))
sk.listen()

# 三次握手
conn, addr = sk.accept()

# 处理收发数据的逻辑
secret_key = "芝麻开门"
res = auth(conn, secret_key)

# 在验证成功之后,给客户端发送状态码
if res:
	conn.send("状态码是200:付款成功~".encode())
# 四次挥手
conn.close()
# 退还端口
sk.close()

五.tcp登录

1.server

import socket
import hashlib
import json

def get_md5_code(usr,pwd):
	hs = hashlib.md5(usr.encode())
	hs.update(pwd.encode())
	return hs.hexdigest()

# res = get_md5_code("tianqi", 777)
# print(res)

sk = socket.socket()
sk.bind(("127.0.0.1", 9000))
sk.listen()
conn, addr = sk.accept()

# 处理收发数据的逻辑
msg = conn.recv(1024).decode()
# 把反解之后的字符串恢复成原来的数据格式,变成字典,通过json
dic = json.loads(msg)
print(dic)

sign = False
with open("userinfo.txt", mode="r", encoding="utf-8") as fp:
	for line in fp:
		usr, pwd = line.strip().split(":")
		# print(usr, pwd)
		if usr == dic["username"] and pwd == get_md5_code(dic["username"], dic["password"]):
			# 制定状态码 0=>失败 1=>成功
			res = {
    
    "code": 1}
			res_msg = json.dumps(res).encode()
			conn.send(res_msg)
			sign = True
			break

	if sign == False:
		# 发送错误的状态码
		res = {
    
    "code": 0}
		res_msg = json.dumps(res).encode()
		conn.send(res_msg)

conn.close()
sk.close()

1.client

import socket
import json
sk = socket.socket()
sk.connect(("127.0.0.1", 9000))

# 处理收发数据的逻辑
usr = input("请输入您的用户名:")
pwd = input("请输入您的密码:")
dic = {
    
    "username": usr, "password": pwd, "operate": "login"}
# 先通过json变成字符串
res = json.dumps(dic)
# json字符串 -> 字节流
bytes_msg = res.encode()
# 把字节流发送给服务器
sk.send(bytes_msg)

# 接收服务器端发送过来的数据
res_msg = sk.recv(1024).decode()
dic_code = json.loads(res_msg)

if dic_code["code"]:
	print("恭喜你,登录成功")
else:
	print("i am so sorry ~ 登录失败")

sk.close()

猜你喜欢

转载自blog.csdn.net/qq_45957580/article/details/108067681