1.加密模块
1.1加密
加密:将明文数据通过一系列算法变成密文的数据,以此保证数据的安全性.
在IT互联网没有绝对的安全,只有更加的安全.
涉及到密码存储:存储的是密文,只有用户自己知道明文.
用户输入的明文经过前/后端程序转为密文进行存储.
1.2碰撞理论
数据泄露:密文算法的设计断绝密文转明文的方法.别人也只能拿到密文.
碰撞理论
通过穷举字符组合的方式得到字符,
在翻译成密文,以此创建了明文密文对应查询数据库.
明文数据只要是相同的,无论如何传递加密都是一样的.
输入的密码加密之后比对加密之后的结果,如果存在则可以找到明文.
ps:
登入程序时,输错密码多次后会限制一个时间内的登入,
就是为了防止'人工智能'写字典破解密码.
1.3加盐处理
加盐处理:在对明文数据加密处理前添加一些干扰项.
自定义的盐 + 明文 == > 算法加密 == 处理后的结果
动态加盐:在对明文数据加盐之前添加动态的干扰项.
不会重复的字符 + 明文 == > 算法加密 == 处理后的结果
eg:当前时间 uuid永远不会重复的字符串...
1.4hashlib
hashlib是Python备内置的加密算法模块.
包含:
1.md系列
2.sha系列
3.base系列
4.hmac系列
密文越长使用的算法越复杂,对应破解算法的难度越高.
产生的复杂的算法,占用的资源越多,基于网络发送需要占据的数据越大.
具体使用什么算法取决于项目的要求,一帮情况下md5足够.
1.5md方法
.md5() 确定md5算法并实例化一个对象.
.update() 需要计算的值,只能接受bytes类型数据.
字符转bytes类型方式:
1.纯数字和字母 b'xxx'
2.'xxx'.encode('utf8')
3.bytes('xxx', 'utf8')
.hexdigest() 得到加密之后的值.
1.6加密使用
import hashlib
md5 = hashlib.md5()
print(md5)
md5.update(b'hello word')
res = md5.hexdigest()
print(res, type(res))
1.7分段传入
明文数据只要是相同的那么无论如何传递,结果都一样的.
import hashlib
md5_1 = hashlib.md5()
md5_2 = hashlib.md5()
md5_1.update(b'abc123')
md5_2.update(b'abc')
md5_2.update(b'123')
print(md5_1.hexdigest())
print(md5_2.hexdigest())
"""
e99a18c428cb38d5f260853678922e03
e99a18c428cb38d5f260853678922e03
"""
1.8碰撞破密
import hashlib
md5 = hashlib.md5()
md5.update('123'.encode('utf8'))
res = md5.hexdigest()
print(res)
![image-20211129155857724](https://i-blog.csdnimg.cn/blog_migrate/e47b900788f25cfda426c39a2621c16a.png)
import hashlib
import random
def get_md5(pwd):
md5 = hashlib.md5()
md5.update(pwd.encode('utf8'))
res = md5.hexdigest()
return res
while True:
pwd = input('输入密码>>>:')
pwd_md5 = get_md5(pwd)
while True:
pwd_list = ['1', '2', '3', '4', '5', '6']
random.shuffle(pwd_list)
my_pwd_str = ''.join(pwd_list)
my_pwd_md5 = get_md5(my_pwd_str)
if my_pwd_md5 == pwd_md5:
print('找到密码了,密码是%s' % pwd_list)
break
1.9加盐处理
import hashlib
import uuid
uid1 = uuid.uuid1()
print(uid1, type(uid1))
uid1 = str(uid1)
print(uid1, type(uid1))
pwd = input('输入你的密码>>>:')
md5 = hashlib.md5()
md5.update(pwd.encode('utf8'))
md5.update(uid1.encode('utf8'))
res = md5.hexdigest()
print(res)
"""
dc65ac64-50f1-11ec-ac0c-b025aa345648 <class 'uuid.UUID'>
dc65ac64-50f1-11ec-ac0c-b025aa345648 <class 'str'>
输入你的密码>>>:123
eac5ab63c0dd6698cf33a92ab159073a
"""
2.文件校验
![image-20211129171655423](https://i-blog.csdnimg.cn/blog_migrate/418bfcfb08e18b2381fbeb963b628a23.png)
2.1检验文件一致性
1.文件 --> 加密 --> 密文
2.下载文件处提供密文或一同下载
3.下载到电脑上后,按说明按通过算法 再计算一次检验密文是否一致.
4.如果密文不一样则文件被改动.否则正常.
(哪怕修改一个字符密码计算结果都不一样)
import hashlib
data = 'abc123456789def'
def get_md5(res):
md5 = hashlib.md5()
md5.update(res.encode('utf8'))
data_md5 = md5.hexdigest()
return data_md5
print(get_md5(data))
with open('a.txt', mode='wt', encoding='utf8') as f0:
f0.write(data)
手动修改一个字符
with open('a.txt', mode='rt', encoding='utf8') as f1:
read_dita = f1.read()
print(get_md5(read_dita))
2.2大文件md5校验
文件不是很大的情况下,可以将所有文件内部全部加密处理,
但如果文件特别大全部加密处理相当耗时耗资源.
处理方案:
针对打文件 可以使用切片读取的方式
随机切几个位置抽取做加密.
1.获取玩文件总大小 os.path.getsize 字节数
2.指定分片读取策略(读几段 每段几个字节)
0, len//4 , len//2, len
开头 四分之1出 二分之1处 末尾
3.比特流技术概念
比特流技术 ---> 迅雷
就近原则:
你电脑有下载者需要的数据 某的用户就近的话,可能从你电脑中读取数据进行下载.
断点续传:
获取当前下载文件的的字节数,在从这个点开始下载.
4.日志模块
4.1日志级别
logging模块
日志有五个级别()
1 .debug() 10
2 .info() 20
3 .waring() *** 30 默认
4 .eroor() **** 40
5 .critical ***** 50
默认记录的级别在30及
4.2详解
方法:
.getLogger('xxx') 产生日志对象
.filter() 负责过滤日志
.FileHandler('a1.log',encoding='utf8') 日志产生的位置
.StreamHandler() 产生到终端
.formatter() 日志的格式
.addHandler() 绑定输出的
.setFormatter() 绑定输出格式
.setLevel() 设置等级
.debug() 写入日志
4.3图解
![image-20211129192522113](https://i-blog.csdnimg.cn/blog_migrate/4ebbbe3c1d6abe652dd7539158de4a1c.png)
4.4format参数
属性名 格式 描述
函数名 %(funcName)s 日志调用所在的函数名
日志级别名称 %(levelname)s 消息的级别名称’DEBUG’,‘INFO’,‘WARNING’,‘ERROR’,‘CRITICAL’
日记级别数值 %(levelno)s 消息的级别数字,对应DEBUG,INFO,WARNING,ERROR,CRITICAL
行号 %(lineno)d 日志调用所在的源码行号
模块 %(module)s 模块(filename的名字部分)
进程ID %(process)d 进程ID
线程ID %(thread)d 线程ID
进程名称 %(processName)s 进程名
线程名称 %(threadName)s 线程名
logger名称 %(name)s logger名
日志消息内容 %(message)s The logged message,computed as msg %args.
当调用Formatter.format()时设置asctime %(asctime)s 创建LogRecord时的可读时间。
默认情况下,它的格式为“2021-11-28 16:49:45,896”(逗号后面的数字是毫秒部分的时间)
import logging
logger = logging.getLogger('程序运行记录')
hd_f1 = logging.FileHandler('log1.log', encoding='utf8')
hd_f2 = logging.FileHandler('log2.log', encoding='utf8')
hd_p = 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(hd_f1)
logger.addHandler(hd_f2)
logger.addHandler(hd_f1)
hd_f1.setFormatter(fm1)
hd_f2.setFormatter(fm2)
hd_p.setFormatter(fm1)
logger.setLevel(10)
logger.debug('第一个日志文件')
4.5配置字典模板
import logging
import logging.config
standard_format = '[%(levelname)s][%(asctime)s][%(threadName)s:%(thread)d][func:%(name)s][%(filename)s:%(lineno)d]' \
'[message:%(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'
},
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'standard',
'filename': logfile_path,
'maxBytes': 1024 * 1024 * 5,
'backupCount': 5,
'encoding': 'utf8',
},
},
'loggers': {
'': {
'handlers': ['default', 'console'],
'level': 'DEBUG',
'propagate': True,
},
},
}
def create_log(name):
"""
:param name: 函数名字
:return: logger1
"""
logging.config.dictConfig(LOGGING_DIC)
logger1 = logging.getLogger(name)
return logger1
from my_log import create_log
logger1 = create_log('登入功能')
logger1.debug('你好')
5.第三方模块
第三方模块,需要基于网络下载.
5.1下载方式1
1. 终端使用pip命令 pip install 模块名
不知道版本默认下载最新的
1.1 需要将pip所有的路径添加到全局变量中,才能使用.
xxx\Python27\Scripts
1.2 直接在\Python27\Scripts的路径 输入cmd
pip3 install 模块名==版本号 指定版本下载
pip3 install 模块名 -i 仓库地址 临时切换
eg: pip3 install openpyxl -i http://mirrors.aliyun.com/pypi/simple/
pip命令默认下载的渠道是国外的python官网(有时候会非常的慢)
我们可以切换下载的源(仓库)
(1)阿里云 http://mirrors.aliyun.com/pypi/simple/
(2)豆瓣 http://pypi.douban.com/simple/
(3)清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
(4)中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
(5)华中科技大学http://pypi.hustunique.com/
![image-20211129210238887](https://i-blog.csdnimg.cn/blog_migrate/e4593c99239c20e50b3ba75bec13ba22.png)
![image-20211129210323573](https://i-blog.csdnimg.cn/blog_migrate/9edfda22c44dd4a208bde710d23573e7.png)
![image-20211129210557487](https://i-blog.csdnimg.cn/blog_migrate/db55a24f049a5175edfaa314eff3cd85.png)
5.2下载方式2
File
settings
project
project interprter
双击或者加号
点击右下方manage管理添加源地址即可
直接使用过年的把国外的源删了
![image-20211129211048454](https://i-blog.csdnimg.cn/blog_migrate/da665297c85ac48a27eb6d5dcf79ff6e.png)
![image-20211129211146169](https://i-blog.csdnimg.cn/blog_migrate/400b4784551409af12c3a80e80e37463.png)
![image-20211129211242449](https://i-blog.csdnimg.cn/blog_migrate/a3dfe7cc34079efe7b7e21155fec3e2b.png)
5.3下载报错
下载第三方模块可能报错的情况及解决措施
1.报错的提示信息中含有关键字timeout
原因:网络不稳定
措施:再次尝试 或者切换更加稳定的网络
2.找不到pip命令
环境变量问题
3.没有任何的关键字 不同的模块报不同的错
原因:模块需要特定的计算机环境
措施:拷贝报错信息 打开浏览器 百度搜索即可
pip下载某个模块报错错误信息
6.Python包
6.1介绍
包:包含模块的文件夹.
一个py文件是一个模块.
6.2包与普通文件夹的区别
包与文件夹:
包:含有一个__init__.py
普通文件夹: 空
6.3导入模块与导入包
模块首次导入发生的3件事:
1.执行文件产生一个全局名称空间
2.执行导入模块语句时,执行模块文件,模块中全部名称,存档到全局名称空间
3.模块文件的全局名称空间绑定给执行文件一个名称
* 之后便可以使用这个名字得到模块文件的全部名称.
包首次导入发生的3件事:
1.执行文件产生一个全局名称空间
2.执行导入包语句时,执行包内的__init__.py文件,文件中产生的名称,存档到全局名称空间
3.__init__.py文件产生的全局名称空间绑定给执行文件一个名称
* 导入包就是导入__init__.py 文件
* 在Python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
Project1
|
|----run.py
|
|---a
|---.__init.py
import a
print(123)
在导入包a的时执行.__init__.py
6.4点符号的作用
导入文件的点代表路径.
执行语句的点代表从名称里空间中取值.
6.5包的使用
在__init__.py 内的名称其他同级文件都能引用.
也不在是导入包内的其他文件.
包内
Project2
|---run.py
|
----a
|
|---.__init__.py ---> 有一个名称 name --指向10
|
|---m1.py ---> print(name) ---> 10
import a
print(a.name)
import a.m1
print('from __init__.py')
name = 10
6.6注意点
__init__py 中:
import m1 这行语句报错
run.py 导入 包 a 执行.__init__.py
.__init__.py的第一条语句是 import m1 报错
原因:这个时候import a 只站在 run.py的角度去导模块m1
直接提示找不到,改为 a.m1 就能找到.