常用模块(二)
一、hashlib模块:
Python中的hashlib模块提供了常见的摘要算法,如MD5,SHA1等等。
1、摘要算法:又称哈希算法、散列算法。它通过一个函数, 把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。
摘要函数是一个单向函数,计算很容易,但反推却很困难而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。
MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。
import hashlib # md5_obj = hashlib.md5() # md5_obj.update(b'alex3714') #使用md5对'alex3714'进行摘要 # ret = md5_obj.hexdigest() #获取摘要后的结果 # print(ret) #aee949757a2e698417463d47acac93df 32位
另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。
比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。
import hashlib sha1_obj = hashlib.sha1() sha1_obj.update(b'alex3714') #使用shai对'alex3714'进行摘要 ret = sha1_obj.hexdigest() #获取摘要后的结果 print(ret) #8a003668a9c990f15148f9e4046e1410781533b6 40位
ps:相同的字符串使用相同的摘要算法 在任何时候 得到的结果都是一样的全世界的md5,sha1都是一样的
ps:update操作可以在hexdigest之前执行多次,分次对字符串进行摘要,结果是对整个场字符串的摘要结果
# md5_obj = hashlib.md5() # md5_obj.update(b'111111') # ret = md5_obj.hexdigest() # print(ret) # 111111:96e79218965eb72c92a549dd5a330112 # md5_obj = hashlib.md5() # md5_obj.update(b'111') ## update操作可以在hexdigest之前执行多次 # md5_obj.update(b'111') # 分次对一个长字符串进行摘要 # ret = md5_obj.hexdigest() # 结果是对整个长字符串的摘要结果 # print(ret) #96e79218965eb72c92a549dd5a330112 #两个的结果是一样的
摘要算法应用:
1、登录:密码不能使用明文存储 应使用摘要算法进行存储
user = input('请输入用户名>>>') pwd = input('请输入密码>>>') md5_obj = hashlib.md5() md5_obj.update(pwd.encode('utf-8')) pwd = md5_obj.hexdigest() if user=='alex' and pwd =='8d5e957f297893487bd98fa830fa6413': print('登陆成功')
由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,
这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:
加盐操作:
md5_obj = hashlib.md5('盐'.encode('utf-8')) md5_obj.update(b'111111') ret = md5_obj.hexdigest() print(ret) 111111:96e79218965eb72c92a549dd5a330112 未加盐时 111111:962d062b5750165f641f182fa9cc9ab6 加盐之后
动态加盐:
# 动态加盐 # username = input('请输入用户名>>>') #67a7603759defee334d6448e25671446 # password = input('请输入密码>>>') # md5_obj = hashlib.md5(username.encode('utf-8') + '盐'.encode('utf-8')) # md5_obj.update(password.encode('utf-8')) # ret = md5_obj.hexdigest() # print(ret)
2.校验文件的一致性:
#校验文件一致性 with open('userinfo','rb') as f : md5_obj =hashlib.md5() md5_obj.update(f.read()) res = md5_obj.hexdigest() print(res) #结果:84b2fe284833ac7903a7ac865e6c27a9 with open('userinfo','rb')as f: md5_obj =hashlib.md5() for line in f: md5_obj.update(line) #update 操作可以在hexdigest之前执行多次 #分次对一个长字符串进行摘要 res = md5_obj.hexdigest() #结果是对一个厂字符串摘要的摘要结果. print(res) # 输出结果 :84b2fe284833ac7903a7ac865e6c27a9
二、configpaser模块:
该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)
1、常见的ini格式:

# init 格式 [北京校区] #section 课程 = python , linux # option python讲师 = egon,alex,taibai linux讲师 = 李导,何首乌 [上海校区] 课程 = linux,go go讲师 = egon linux讲师 = 李导,何首乌
2、用python生成一个ini文档
import configparser config =configparser.ConfigParser() config['DEFAULT'] = {'serveraliveinterval':45, 'compression':'yes', 'compressionlevel':9, 'forwardx11':'yes'} config['bitbucket.org']= {'user':'hg'} config['topsecret.server.com'] = {'host port':50022, 'forwardx11':'no'} with open('new1.ini','a') as f: config.write(f)
3、ini文档的增、删、改、查
import configparser config = configparser.ConfigParser() print(config.sections()) config.read('new1.ini') print(config.sections()) print('bitbucket.org' in config) print('DEFAULT' in config) print(config['DEFAULT']['compressionlevel']) print(config['topsecret.server.com']['host port']) for key in config['topsecret.server.com']: #有default时会默认打印default的键 print(key) print(config.options('topsecret.server.com')) print(config.items('topsecret.server.com')) print(config.get('topsecret.server.com','host port')) #查 config.add_section('xxxx') #增加一个zu config.remove_option('DEFAULT','forwardx1') #删除一个项 config.set('bitbucket.org','user','6666') #修改一个项 config.remove_section('bitbucket.org') #删除一个组 config.write(open('new1.ini','w')) #写入文件
三、logging模块:
操作日志的模块 日志: 给用户看的 用户的重要行为 登录 涉及安全 账单 钱 给开发运维及测试人员看的 自测 logging.debug('一些中间结果') 测试 1++++++1 运维 记录 打印在屏幕上 写入文件里 logging的优势 格式更加规范 等级更加鲜明
1、logging模块简单的配置用法:
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s [line:%(lineno)s] %(levelname)s %(message)s,', datefmt = '%a, %d %b %Y %H:%M:%S',) # filename = 'test.log', # filemode='w') logging.debug('debug massage') #调试 logging.info('info massage') #信息 logging.warning('warning massage') #警告 logging.error('error massage') #错误 logging.critical('critical massage') #严重错误 默认只打印warning及以上登记的信息 要想全打印 需要在前面加上 logging.basicConfig(level=logging.DEBUG)
2、使用logger对象的用法:
import logging # 首先创建一个logger对象 logger= logging.getLogger() fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 创建一个文件句柄 控制向哪个文件中输出 用什么格式 以及等级 fh = logging.FileHandler('test2.log',encoding='utf-8') fh.setFormatter(fmt) # 创建一个屏幕句柄 控制向屏幕输出 用什么格式 以及等级 sh = logging.StreamHandler() sh.setFormatter(fmt) # 将logger对象和文件句柄,屏幕句柄绑在一起 logger.addHandler(fh) logger.addHandler(sh) logger.setLevel(logging.DEBUG) sh.setLevel(logging.INFO) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message')
3、logger配置参数:

import logging logger = logging.getLogger() # 创建一个handler,用于写入日志文件 fh = logging.FileHandler('test.log',encoding='utf-8') # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 logger.addHandler(ch) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message')