hashilib模块
我们的登录密码在数据库中不能存明文,当别人拿到数据库,看到账号密码是很恐怖的事情。所以我们就需要hashilib模块来加密。前几年csdn的数据库外泄,而且存的是明文,就很麻烦,所幸并不没有涉及大量¥。
# 导入模块
import hashlib
# 实例化md5算法,不可逆,所谓破解都是撞库。对于同一个字符串,进行md5计算,得到的值是一样的。那么我们存入数据库的时候加密,在验证登录时,密码也进行加密对比即可。
md5 = hashlib.md5()
# 加密 bytes类型
md5.update(b'123456')
# 取出来
print(md5.hexdigest())
在hashlib中还有其他加密,sha等算法。使用方法一致,除了实例化的时候不一样,其他一致。
sha有很多种,有的计算的短,有的计算的长,越长越安全,但是时间成本越高。
hashlib不仅仅可以对密码进行加密,根据加密的特性,比如我们用qq传文件,在传送完成的时候,用md5加密,对比两个md5是否一致,一致说明文件是相同的。md5不仅可以对字符串进行加密,也可以对文件等进行加密。以此来检验文件的一致性。
为防止撞库:
import hashlib
# 这里的jiami叫做加盐。
md5 = hashlib.md5(bytes('jiami',encoding='utf-8'))
md5.update(b'123456')
print(md5.hexdigest())
# 动态加盐
使用用户名的一部分或者用户名的一部分再拼接一个字符串的方式作为盐。
configparser模块
处理配置文件的模块。
# 导入模块
import configparser
# 实例化
config =configparser.ConfigParser()
# 定义配置文件的内容
config['DEFAULT'] = {
'author':'张三',
'age':'18',
'sex':'男'
}
config['path'] = {
'path1':'D:/python'
}
# 写入配置文件
with open('config.ini','w') as configfile:
config.write(configfile)
就会是个生成一个config.ini的文件,内容为:
[DEFAULT]
author = 张三
age = 18
sex = 男
[path]
path1 = D:/python
[DEFAULT]和[path]叫做组,以分组的形式来写配置文件。
其他操作:
read(filename) # 读取配置文件,直接读取ini文件内容
sections() # 获取ini文件内所有的组,以列表形式返回,除了DEFAULT
options(sections) # 获取指定组下所有options ,以列表形式返回
items(sections) # 获取指定组下所有的键值对
get(section, option) # 获取组中option的值,返回为string类型
实例:
import configparser
config =configparser.ConfigParser()
# 读取配置文件
config.read('config.ini')
# 输出所有组的组名,这里输出['path'],['DEFAULT']很特殊,不会显示
print(config.sections())
# 输出一个组下的名字 输出['path1', 'author', 'age', 'sex']会把默认的也输出
print(config.options('path'))
# 输出[('author', '张三'), ('age', '18'), ('sex', '男'), ('path1', 'D:/python')]
print(config.items('path'))
# 输出D:/python
print(config.get('path', 'path1'))
# 判断一个组是否在其中
print('path' in config) # True
# 其他取值方式
print(config['path']['path1']) # D:/python
# 也可以循环一个组
for key in config['path']:
print(key)
# 添加一个组
config.add_section('name')
# 添加一个组的配置
config.set('path','path1','123456')
# 添加一个配置
config.set('name','name1','李四')
# 删除一个组
config.remove_section('path')
# 删除一个组中的某个配置
config.remove_option('path','path1')
# 最后都需要写入
config.write(open('config.ini',w))
logging模块
日志模块,记录用户的操作,代码的执行过程以及来帮我们排除错误。
import logging
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
输出:
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
只输出了上面三个,打印是有级别的,从小到下,依次由低级别到高级别
DEBUG:排错信息
INFO:正常信息
WARNING:表示警告
error:表示错误
CRITICAL:严重错误
程序默认是从WARNING开始输出的。
配置日志级别,格式,输出
import logging
logging.basicConfig(level = logging.DEBUG,
format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s - %(message)s',
datefmt = '%a, %d %b %H:%M:%S',
filename = 'test.log',
filemode = 'w'
)
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
生成一个test.log文件:
Sun, 18 Nov 14:05:25 Demo.py[line:249] DEBUG - debug message
Sun, 18 Nov 14:05:25 Demo.py[line:250] INFO - info message
Sun, 18 Nov 14:05:25 Demo.py[line:251] WARNING - warning message
Sun, 18 Nov 14:05:25 Demo.py[line:252] ERROR - error message
Sun, 18 Nov 14:05:25 Demo.py[line:253] CRITICAL - critical message
level:指定输出的级别,我们这里选择的DEBUG,为最小的级别,所以都输出了
format:格式化输出
%(levelno)s:打印日志级别的数值
%(levelname)s:打印日志级别的名称
%(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s:打印当前执行程序名
%(funcName)s:打印日志的当前函数
%(lineno)d:打印日志的当前行号
%(asctime)s:打印日志的时间
%(thread)d:打印线程ID
%(threadName)s:打印线程名称
%(process)d:打印进程ID
%(message)s:打印日志信息
datefmt:时间的格式
filename:文件的名字
filemode:文件打开方式
用自带的方法有很多局限性:比如用自带的写入的日志文件为中文会乱码,不能同时输出到文件和屏幕,我们自己来写一下。
实例:
import logging
# 创建一个对象
logger = logging.getLogger()
# 创建一个文件操作
fh = logging.FileHandler('test.log',encoding='utf-8')
# 创建一个屏幕输出
sh = logging.StreamHandler()
# 添加到文件的级别
logger.setLevel(logging.DEBUG)
# 输出到屏幕的级别
logger.setLevel(logging.DEBUG)
# 定义一个格式
format = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s - %(message)s')
# 格式作用于文件
fh.setFormatter(format)
# 格式作用于屏幕输出
sh.setFormatter(format)
# 文件作用于对象
logger.addHandler(fh)
# 屏幕输出添加到对象
logger.addHandler(sh)
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
文件和屏幕都会输出:
2018-11-18 14:48:38,059 Demo.py[line:274] DEBUG - debug message
2018-11-18 14:48:38,060 Demo.py[line:275] INFO - info message
2018-11-18 14:48:38,060 Demo.py[line:276] WARNING - warning message
2018-11-18 14:48:38,060 Demo.py[line:277] ERROR - error message
2018-11-18 14:48:38,060 Demo.py[line:278] CRITICAL - critical message