hashlib加密模块
1.hashlib的简介
hashlib 是一个提供了一些流行的hash(摘要)算法的Python标准库.其中所包括的算法有 md5, sha1, sha224, sha256, sha384, sha512等
hashlib是将明文数据处理成密文数据,让外人无法看懂,保证了数据的安全性。数据加密是把明文数据变成一串没有规律的字符串(数字、字母、符号)。密文越长表示加密算法的过程就越复杂。
2.hashlib的基本操作
import hashlib
md5=hashlib.md5()#选择加密算法
md5.update(b'hello')#传入名问数据
res=md5.hexdigest()#获取加密密文
print(res)#5d41402abc4b2a76b9719d911017c592
sha1=hashlib.sha1()#选择加密算法
sha1.update(b'hello')#传入名问数据
res=sha1.hexdigest()#获取加密密文
print(res)#aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
加密补充说明
1.加密算法不变 内容如果相同 那么结果肯定相同
import hashlib
md5=hashlib.md5()#选择加密算法
md5.update(b'hello word')
res=md5.hexdigest()
print(res)#13574ef0d58b50fab38ec841efe39df4
md5=hashlib.md5()#选择加密算法
md5.update(b'hello ')
md5.update(b'word')
res=md5.hexdigest()
print(res)#13574ef0d58b50fab38ec841efe39df4
2.加密之后的结果是无法反解密的
只能从明文到密文正向推导 无法从密文到明文反向推导
常见的解密过程其实是提前猜测了很多种结果
123 密文
321 密文
222 密文
3.加盐处理
在明文里面添加一些额外的干扰项
md5=hashlib.md5()#加盐处理
md5.update('干扰项'.encode('utf8'))
md5.update(b'hello word')
res=md5.hexdigest()
print(res)#ad4348185523194c41e11f65676e8e24
4.动态加盐
当前时间 用户名的部分 uuid(随机字符串(永远不会重复))
干扰项是随机变化的
import time
md5 = hashlib.md5()
# 把添加时间当作干扰向项
salt = time.time()
salt = str(salt)
md5.update(salt.encode('utf8'))
md5.update('123456'.encode('utf8'))
password = md5.hexdigest()
print(password)
# 46152da37b6d8096cdb144c3ccb6468a
有些所谓的破解密码网站,其实就是把尽可能多的可能输入的明文全部加密一遍,把密文保存起来,用户输入他的密文后,从数据库中找出相同的密文配对,从而判断明文是什么...
5.加密实战操作
1.用户密码加密
2.文件安全性校验
3.文件内容一致性校验
4.大文件内容加密
截取部分内容加密即可
md5 = hashlib.md5()
with open(r'a.txt', 'rb') as f:
for line in f:
md5.update(line)
real_data = md5.hexdigest()
print(real_data) # 29d8ea41c610ee5d1e76dd0a42c7e60a
with open(r'a.txt', 'rb') as f:
for line in f:
md5.update(line)
error_data = md5.hexdigest()
print(error_data) # 738a56b49f24884ba758d1e4ab6ceb74
import os
# 读取文件总大小
res = os.path.getsize(r'a.txt')
# 指定分片读取策略(读几段 每段几个字节) 10 f.seek()
read_method = [0, res // 4, res // 2, res]
# 用f.read(10)读取十个字符
# 读取到最后的位置时需要把光标往前移动
subprocess模块
import subprocess
res=subprocess.Popen(
'ipconfig ',#操作系统执行的指令
shell=True,#固定配置
stdin=subprocess.PIPE,#输入指令
stdout=subprocess.PIPE,#输出指令
)
print('正确结果',res.stdout.read().decode('gbk'))
print('错误结果',res.stderr)
正确结果
Windows IP 配置
logging日志模块
1如何理解日志
简单的理解为是记录行为举止的操作
2日志的级别
五种级别
debug:可以帮助我们在平时的开发过程中,帮助我们查看一些输出的信息是否正确。它可以替代我们平时使用的 print() 函数。
info:它代表了一般的消息类信息,只是为了记录一些程序的行为,比如程序执行到了某个位置,进行一些简单的记录。
warnning:该等级是一种警告,一般来说程序不会出错,但是可能存在一定的潜在风险。
error:一般对应业务中出现了重大问题。比如异常或者业务逻辑不应该执行到某种情况。我们都可以通过error来进行记录。
critical:比 error 更严重的级别,不过一般来说 error 级别已经很严重了,所以 critical 很少使用。
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
eg:
import logging
logging.debug('debug message')
logging.info('info message')
#只有高于info级别的日志bug才会显示
logging.warning('warning message')#WARNING:root:warning message
logging.error('error message')#ERROR:root:error message
logging.critical('critical message')#CRITICAL:root:critical message
file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf8',)
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
handlers=[file_handler,],
level=logging.ERROR
)
logging.error('我在这等你呢')


日志的组成

1.产生日志
2.过滤日志
3.输出日志
4.日志格式
import logging
logger=logging.getLogger('购物车记录')#1日志的产生
hd1=logging.FileHandler('a1.log',encoding='utf8')#输出到文件
hd2=logging.FileHandler('a2.log',encoding='utf8')#输出到文件
hd3=logging.StreamHandler()# 输出到终端
fm1=logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
)#日志的格式(包装)
fm2 = logging.Formatter(
fmt='%(asctime)s - %(name)s: %(message)s',
datefmt='%Y-%m-%d',
)
logger.addHandler(hd1)#给logger对象绑定handler对象
logger.addHandler(hd2)
logger.addHandler(hd3)
hd1.setFormatter(fm1)#给handler绑定formmate对象
hd2.setFormatter(fm2)
hd3.setFormatter(fm1)
logger.setLevel(10)#debug
logger.debug('略略略')
#2022-10-27 17:27:13 PM - 购物车记录 - DEBUG -333: 略略略
#2022-10-27 - 购物车记录: 略略略
日志配置字典
import logging
import logging.config
standard_format='[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]'
simple_format='[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
logfile_path='a3.log'
LOGGING_DIC={
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {}, # 过滤日志
'handlers': {
# 打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
# 打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
# logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
}, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
# '购物车记录': {
# 'handlers': ['default','console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
# 'level': 'WARNING',
# 'propagate': True, # 向上(更高level的logger)传递
# }, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
},
}
logging.config.dictConfig(LOGGING_DIC)
logger1=logging.getLogger('消费记录')
logger1.debug('啦啦啦')
#[2022-10-27 18:51:12,860][MainThread:13832][task_id:消费记录][333.py:140][DEBUG][啦啦啦]
#[DEBUG][2022-10-27 18:51:12,860][333.py:140]啦啦啦