目录
1.什么是序列化
序列化指的是把内存的数据类型转换成一个特定的格式的内容
该格式的内容可用于存储或者传输给其他平台使用
内存中的数据类型--->序列号---->特定的格式(json格式或者pickle格式)
内存中的数据类型<---反序列号<----特定的格式(json格式或者pickle格式)
为何要序列号
序列化得到特定格式的结果有两种用途
1.可用于存储 => 用于存档
2.传输给其他平台使用 => 跨平台数据交互
强调
针对用途一的特定格式:可以是一种专用的格式=>pickle只有python可以识别
针对用途二的特定格式:应该是一种通用,能够被各种语言识别的格式=>
如何序列化和反序列化
json模块
import json
json_res=json.dumps(['aaa',True,False])
print(json_res)
with open('a.txt','w',encoding='utf-8') as f:
f.write(json_res)
# json.dump(['aaa',True,False],f)
l=json.loads(json_res)
print(l,type(l))
with open('a.txt','r',encoding='utf-8') as f:
res=f.read()
l=json.loads(res)
# l=json.load(f)
print(l)
json验证:json格式兼容的是所有语言通用的数据类型,不能识别某已语言所独有类型
json.loads({1,2,3,4,5})
强调
json字符串格式用" " 双引号
json反序列化必须用json格式,也可以在之前+b
l=json.loads(b'["aaa",True,False]')
pickle模块
import pickle
res=pickle.dumps({1,2,3,4,5})
print(res,type(res))
s=pickle.loads(res)
print(s,type(s))
= = = = = = = =了解= = = = = = = = =
coding:utf-8
import pickle
with open('a.pkl',mode='wb') as f:
# 一:在python3中执行的序列化操作如何兼容python2
# python2不支持protocol>2,默认python3中protocol=4
# 所以在python3中dump操作应该指定protocol=2
pickle.dump('你好啊',f,protocol=2)
with open('a.pkl', mode='rb') as f:
# 二:python2中反序列化才能正常使用
res=pickle.load(f)
print(res)
2.猴子补丁
一.什么是猴子补丁?
猴子补丁的核心就是用自己的代码替换所用模块的源代码,详细地如下
1,这个词原来为Guerrilla Patch,杂牌军、游击队,说明这部分不是原装的,在英文里guerilla发音和gorllia(猩猩)相似,再后来就写了monkey(猴子)。
2,还有一种解释是说由于这种方式将原来的代码弄乱了(messing with it),在英文里叫monkeying about(顽皮的),所以叫做Monkey Patch。
二. 猴子补丁的功能(一切皆对象)
1.拥有在模块运行时替换的功能, 例如: 一个函数对象赋值给另外一个函数对象(把函数原本的执行的功能给替换了)
class Monkey:
def hello(self):
print('hello')
def world(self):
print('world')
def other_func():
print("from other_func")
monkey = Monkey()
monkey.hello = monkey.world
monkey.hello()
monkey.world = other_func
monkey.world()
三.monkey patch的应用场景
如果我们的程序中已经基于json模块编写了大量代码了,发现有一个模块ujson比它性能更高,
但用法一样,我们肯定不会想所有的代码都换成ujson.dumps或者ujson.loads,那我们可能会想到这么做
import ujson as json
但是这么做的需要每个文件都重新导入一下,维护成本依然很高,此时我们就可以用到猴子补丁了, 只需要在入口加上:
import json
import ujson
def monkey_patch_json():
json.__name__ = 'ujson'
json.dumps = ujson.dumps
json.loads = ujson.loads
monkey_patch_json() # 之所以在入口处加,是因为模块在导入一次后,后续的导入便直接引用第一次的成果
其实这种场景也比较多, 比如我们引用团队通用库里的一个模块, 又想丰富模块的功能, 除了继承之外也可以考虑用Monkey
Patch.采用猴子补丁之后,如果发现ujson不符合预期,那也可以快速撤掉补丁。个人感觉Monkey
Patch带了便利的同时也有搞乱源代码的风险
3.configparser模块
配置文件格式
import configparser
config=configparser.ConfigParser()
config.read('test.ini')
获取section
print(config.sections())
获取section下的options
print(config.options('section1'))
获取items
print(config.items('section1'))
获取值
print(config.get('section1','user'))
print(config.getint('section1','age'))
4.hashlib模块
1.什么是hash:
hash一类算法,该算法接受传入的内容,经过运算得到一串hash值
hash值的特点:
I 只要传入的内容一样,得到的hash值必然一样
II 不能由hash值返解成内容
III 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定
2、hash的用途
用途1:特点II用于密码密文传输与验证
用途2:特点I、III用于文件完整性校验
3.如何用hash
import hashlib
m=hashlib.md5()
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))
res=m.hexdigest()
f=open('a.txt','rb')
f.seek()
f.read(2000)
m.update()
m.hexdigest()
模拟撞库
import hashlib
cryptograph = 'aee949757a2e698417463d47acac93df'
passwds = [
'alex3714',
'alex1313',
'alex94139413',
'alex123456',
'123456alex',
'a123lex',
]
dic = {}
for i in passwds:
res = hashlib.md5(i.encode('utf-8'))
dic[i] = res.hexdigest()
for k, v in dic.items():
if v == cryptograph:
print(f'撞库成功,明文密码是{k}')
break
提升撞库的成本=>密码加盐
import hashlib
m=hashlib.md5()
m.update('天王'.encode('utf-8'))
m.update('alex3714'.encode('utf-8'))
m.update('盖地虎'.encode('utf-8'))
print(m.hexdigest())
import subprocess
obj=subprocess.Popen('echo 123 ; ls / ; ls /root',shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
print(obj)
res=obj.stdout.read()
print(res.decode('utf-8'))
err_res=obj.stderr.read()
print(err_res.decode('utf-8'))
homework
# 1、把登录与注册的密码都换成密文形式
import hashlib
def register():
inp_usernmae=input('请输入用户名:')
inp_password=input('请输入密码:')
re_password=input('请再次输入密码:')
if inp_password==re_password:
m=hashlib.md5()
m.update(inp_password.encode('utf-8'))
password=m.hexdigest()
print('注册成功')
with open('db.txt','w',encoding='utf-8') as w:
w.write(f'{inp_usernmae}:{password}\n')
else:
print('两次密码不一致')
def login():
while True:
inp_username=input('请输入账号:')
inp_password=input('请输入密码:')
with open('db.txt','r',encoding='utf-8') as f:
for line in f:
user,pwd=line.strip().split(':')
if inp_username==user:
m=hashlib.md5()
m.update(inp_password.encode('utf-8'))
inp_password=m.hexdigest()
if inp_password==pwd:
print('登录成功')
return
else:
print('密码错误')
# 2、文件完整性校验(考虑大文件)
m=hashlib.md5()
f=open('a.txt','rb')
f.seek()
f.read(2000)
m.update()
m.hexdigest()
# 3、注册功能改用json实现
import hashlib
import json
def register():
inp_username=input('请输入用户名:')
inp_password=input('请输入密码:')
re_password=input('请再次输入密码:')
if inp_password==re_password:
m=hashlib.md5()
m.update(inp_password.encode('utf-8'))
password=m.hexdigest()
print('注册成功')
with open('db.txt','w',encoding='utf-8') as w:
user=json.dumps([inp_username])
pwd=json.dumps([password])
w.write(f'{user}:{pwd}')
else:
print('两次密码不一致')
# 4、项目的配置文件采用configparser进行解析
import configparser
config=configparser.ConfigParser()
config.read('test.ini')
# 获取section
print(config.sections())
# 获取section下的options
print(config.options('section1'))
# 获取items
print(config.items('section1'))
返回