hashlib加密模块
1.什么是加密:将明文数据(看得懂)经过处理之后变成密文数据(看不懂)的过程
2.为什么要加密:不想让敏感的数据轻易的泄露
3.如何判断当前数据值是否已经加密:一般情况下如果是一串没有规则的数字字母符合的组合一般都是加密之后的结果
4.加密算法:就是对明文数据采用的加密策略
不同的加密算法复杂度不一样 得出的结果长短也不一样
通常情况下加密之后的结果越长 说明采用的加密算法越复杂
5.常见加密算法:md5 sha系列 hmac base64
6.代码实参
import hashlib
md5 = hashlib.md5() 选择md5加密算法作为数据的加密策略
md5.update(b'123') 往里面添加明文数据 数据必须是bytes类型
res = md5.hexdigest() 获取加密之后的结果
print(res) 202cb962ac59075b964b07152d234b70
加密模块补充说明
<1.加密之后的结果一般情况下不能反解密
202cb962ac59075b964b07152d234b70
所谓的反解密很多时候其实是偷换概念
提前假设别人的密码是什么 然后用各种算法算出对应的密文
之后构造对应关系 然后比对密文 最终映射明文
{'密文1':123,'密文2':321,...}
<2.只要明文数据是一样的那么采用相同的算法得出的密文肯定一样
import hashlib
md5 = hashlib.md5() 选择md5加密算法作为数据的加密策略
md5.update(b'123') 往里面添加明文数据 数据必须是bytes类型
md5.update(b'hello') 往里面添加明文数据 数据必须是bytes类型
md5.update(b'jason') 往里面添加明文数据 数据必须是bytes类型
res = md5.hexdigest()
print(res) 31b9a81dc788368469ee4b78877eb1eb
md5.update(b'123hellojason')
res = md5.hexdigest()
print(res) 31b9a81dc788368469ee4b78877eb1eb
<3.加盐处理(salt)
password = input('password>>>:').strip()
md5.update('公司设置的盐(干扰项)'.encode('utf8'))
md5.update(password.encode('utf8'))
res = md5.hexdigest()
print(res) 78bf5bd131c520b54168206d75f9f9be
<4.动态加盐(salt)
干扰项每次都不一样
每次获取当前时间 每个用户用户名截取一段
<5.加密实际应用场景
1.用户密码加密:注册存储密文 登录也是比对密文
2.文件安全性校验:正规的软件程序写完之后做一个内容的加密
网址提供软件文件记忆该文件内容对应的密文
用户下载完成后不直接运行 而是对下载的内容做加密
然后比对两次密文是否一致 如果一致表示文件没有被改
不一致则表示改程序有可能被植入病毒
3.大文件加密优化
程序文件100G ,一般情况下读取100G内容然后全部加密 太慢,不对100G所有的内容加密 而是截取一部分加密
每隔500M读取30bytes
subprocess模块
模拟计算机cmd命令窗口
import subprocess
cmd = input('请输入您的指令>>>:').strip()
sub = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout执行命令之后正确的返回结果
print(sub.stdout.read().decode('gbk'))
stderr执行命令报错之后的返回结果
print(sub.stderr.read().decode('gbk'))
日志模块
日志模块需要你写的代码很少 几乎都是CV
1.什么是日志:日志就类似于是历史记录
2.为什么要使用日志:为了记录事物发生的事实(史官)
3.如何使用日志
3.1.日志等级
import logging
logging.debug('debug等级')
logging.info('info等级')
logging.warning('warning等级')
logging.error('error等级')
logging.critical('critical等级')
3.2.基本使用
import logging
file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
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('我不好!!!')
日志模块组成部分
import logging
1.日志的产生(准备原材料) logger对象
logger = logging.getLogger('购物车记录')
2.日志的过滤(剔除不良品) filter对象>>>:可以忽略 不用使用
3.日志的产出(成品) handler对象
hd1 = logging.FileHandler('a1.log', encoding='utf-8')
hd2 = logging.FileHandler('a2.log', encoding='utf-8')
hd3 = logging.StreamHandler()
4.日志的格式(包装) format对象
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',
)
5.给logger对象绑定handler对象
logger.addHandler(hd1)
logger.addHandler(hd2)
logger.addHandler(hd3)
6.给handler绑定formmate对象
hd1.setFormatter(fm1)
hd2.setFormatter(fm2)
hd3.setFormatter(fm1)
7.设置日志等级
logger.setLevel(10) debug
8.记录日志
logger.debug('写了半天 好累啊 好热啊')
在以后需要写日志的时候不要按着上面的操作 gai'mo'kuai可以直接调用
日志配置字典
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]' #其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
自定义文件路径
logfile_path = 'a3.log'
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.warning('尊敬的VIP客户 晚上好 您又来啦')
logger1 = logging.getLogger('注册记录')
logger1.debug('jason注册成功')
logger1 = logging.getLogger('红浪漫顾客消费记录')
logger1.debug('慢男 猛男 骚男')
实战应用
按照软件开发目录规范编写使用
日志字典数据应该放在哪个py文件内
字典数据是日志模块固定的配置 写完一次之后几乎都不需要动
它属于配置文件
配置文件中变量名推荐全大写
该案例能够带你搞明白软件开发目录规范中所有py文件的真正作用
def get_logger(msg):
记录日志
logging.config.dictConfig(settings.LOGGING_DIC) 自动加载字典中的配置
logger1 = logging.getLogger(msg)
logger1.debug(f'{username}注册成功') 这里让用户自己写更好
return logger1