hashlib模块
通过摘要算法对数据进行摘要得到一个无规律的数据
常用于密码安全,数据保密等等
摘要算法对同一个数据进行摘要,得到的结果是一致的
摘要算法的用途: 1.密码的密文存储 2.文件一致性检验
密文获取
import hashlib
md5 = hashlib.md5() #得到一个md5对象
md5.update(bytes('哈哈',encoding = 'utf-8'))
#进行摘要,需要bytes类型数据作为参数
print(md5.hexdigest()) #获取摘要后的密文 8c8fa3529ee34d4e69a0baafb7069da3
摘要算法是一堆算法的统称,常用的是md5,sha1,sha224,sha256等等
同一个数据使用同一个算法进行摘要,得到的值总是一致的
同一个数据使用不同的算法进行摘要,得到的值是不一样的
可以使用hashlib模块来调用不同的算法
import hashlib
sha256 = hashlib.sha256() #得到一个sha256对象
sha256.update(bytes('哈哈',encoding = 'utf-8'))
#进行摘要,需要bytes类型数据作为参数
print(sha256.hexdigest()) #获取摘要后的密文
#7a655569d7aab2029ca20b72aea1237bb7852fc2a5b4a297e9a49b4fed453b2a
md5算法从原理上来说是不可破解,但是md5的明文和密文是一一对应,
只要大多数已知的密文放入一个文件库中,
拿未知的密文去做对比,找到文件库中相同的密文就可以得出对应的明文,这就是md5的撞库
因此md5并不安全
文件一致性
#文件一致性校验简略代码
import hashlib
def file_sha256(filepath):
sha256 = hashlib.sha256() #获取一个sha256对象
with open(filepath, 'rb') as f:
for i in f:
sha256.update(i) #对二进制内容进行摘要
return sha256.hexdigest() #返回摘要的结果
def consistency(filepath1,filepath2):
if file_sha256(filepath1) == file_sha256(filepath2):
return True
return False
result = consistency('filedown','file')
print(result)
configparser模块
设置配置文件的模块,对格式有特殊要求
在配置文件中可以设置我们需要的一些属性
修改时只需要修改部分属性而不用改动代码了
设置配置文件
import configparser
config = configparser.ConfigParser() #实例化一个configparser对象
#以组的形式配置
config['DEFAULT'] = {'test' : 0,
'test2':1
}
config['flag'] = {'methodflag' : False,
'wrag':False
}
config['http'] = {'ip':'127.0.0.1',
'port':8080
}
#生成配置文件
with open('example.ini', 'w')as f:
config.write(f)
'''
example.ini:
[flag]
methodflag = False
wrag = False
[http]
ip = 127.0.0.1
port = 8080
'''
'''
配置文件example.ini:
形式: [组名]
key = value
[flag]
methodflag = False
wrag = False
[http]
ip = 127.0.0.1
port = 8080
'''
设置配置文件
import configparser
config = configparser.ConfigParser() #实例化一个configparser对象
config.read('example.ini') #先读取配置文件
print(config.sections()) #['flag', 'http'] 获取文件中所有的组名,不包括DEFAULT
print('DEFAULT' in config) #True 查看组名是否在这个配置文件中
print(config['flag']['methodflag']) #获取组下面键对应的值
for i in config['flag']:#获取组下面所有的key
print(i) #DEFAULT组下的key也会输出
#DEFAULT组是一个特殊的组,config.sections()无法显示它,同时用for循环取任意组名下的值,
#那么DEFAULT组下的数据也会一起输出
print(config.options('flag')) #返回组下所有的key,包括DEFAULT组下的key
print(config.items('flag')) #返回组下所有的键值对元组形式组成的列表,包括DEFAULT组下的键值对
print(config.get('flag','methodflag')) #根据组名和key获取value值
config.add_section('y') #添加组名
config.remove_section('y') #删除组名
config.set('section', 'option', 'value') #添加组中的一条配置项
config.remove_option('section', 'option') #删除组中一条配置项
with open('example.ini', 'w')as f: #写入新文件
config.write(f)
logging模块
日志模块,记录用户行为或代码执行过程
import logging
logging.debug('debug message') #排错信息
logging.info('info message') #正常信息
logging.warning('warning message') #警告信息
logging.error('error message') #错误信息
logging.critical('critical message') #严重错误信息
简单的配置可以使日志信息更完善
1.basicConfig对象,配置简单,能做的事情较少
2.log对象,配置稍微复杂,能做的事情较多 (推荐)
#basicConfig对象
import logging
#获取日志的文件处理对象
file_handler = logging.FileHandler(filename='file', mode='a', encoding='utf-8')
#获取一个basicConfig对象
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.DEBUG #输出DEBUG级别及以上所有信息
)
#制造一个错误
try:
a = 1 / 0
print(a)
except ZeroDivisionError: #错误信息进行捕获并写入相关提示信息到日志中
logging.error('此处发生ZeroDivisionError错误')
#日志文件中的信息
#2020-01-25 23:25:57 PM - root - ERROR -fun43: 此处发生ZeroDivisionError错误
format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息
#log对象
import logging
logger = logging.getLogger() #获取log对象
#获取文件处理器对象
filelog = logging.FileHandler('file',encoding='utf-8')
filelog.setLevel(logging.DEBUG) #设置日志文件的输出级别
#获取屏幕处理器对象
streamlog = logging.StreamHandler()
streamlog.setLevel(logging.DEBUG) #设置屏幕的输出级别
#设置日志格式
format1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
format2 = logging.Formatter('%(asctime)s - %(name)s - %(filename)s - %(levelname)s - %(message)s')
#为文件对象绑定日志的格式
filelog.setFormatter(format1)
#为屏幕对象绑定日志的格式
streamlog.setFormatter(format2)
#为log对象绑定文件对象和屏幕对象
logger.addHandler(filelog)
logger.addHandler(streamlog)
try:
a = 1 / 0
print(a)
except ZeroDivisionError:
logger.error('此处发生ZeroDivisionError错误---log')
#屏幕输出: 2020-01-25 23:53:35,341 - root - fun.py - ERROR - 此处发生ZeroDivisionError错误---log
#文件记录:2020-01-25 23:53:35,341 - root - ERROR - 此处发生ZeroDivisionError错误---log
#总结流程:创建log对象,为对象绑定处理器对象,为处理器对象绑定日志格式