模块补充,hashlib,logging,configparser模块
复习
多态:python 自带多态
java的多态是通过继承来实现的
钻石继承
新式类,继承object类
找名字的时候,广度优先
python3中全是新式类,默认继承object
mro方法,super方法
经典类
只会出现在python2中,不主动继承object
找名字的时候,深度优先
封装
私有的 __名字
私有的对象属性
私有的静态属性
私有方法
不能从外部调用,不能被子类继承
在类的内部使用时,自动变形为:_类__名字
@property 把一个方法伪装成一个属性
@名字.setter 在修改一个属性的时候调用这个方法
@名字.deleter 在 del.属性名 的时候调用这个方法
@classmothod
类方法
调用者是一个类
有默认参数cls,cls表示当前类
在什么时候使用类方法?
只是用类中的静态变量
或者类方法或者静态方法的时候
@staticmethod 静态方法
调用者也是一个类
没有默认必须传的参数
什么时候用静态方法?
既不会用到对象的资源也不会用到类的资源的时候
hash()
把一个数据转换成一个数字的算法
在同一次执行的过程中,对同一个可哈希的值进行计算,得出的结果总是相同的
做什么用的
有什么特点
基础数据类型的时候
不可变数据类型可哈西
可变数据类型不可哈希
print(hash('abc'))#8863356200575210437
print(hash('abc'))#8863356200575210437
print(hash('abc'))#8863356200575210437
字典
集合
在数据的储存方面提供优化的
为什么同一个值计算hash值每次运行结果不同?
每次执行所获得的的内存空间都不一定相同,所以多次执行统一代码得到的hash值可能不同
hashlib模块
hashlib的特点
是一个模块,提供多种算法
同一字符串用同一算法进行加密,结果总是相同的
同一字符串用不同的算法进行加密,结果总是不同的
为什么使用hashlib进行加密呢?
1.登录
123-->转换-->转换之后的结果储存在文件里
用户登录的时候
输入密码-->用同样的方法转换-->结果于文件中匹配
import hashlib
hashlib.sha1()
md5算法,sha 算法
字符串-->加密的结果
md5算法--暴力破解,撞库
sha算法--是一个算法集
随着后面的数字越大,计算的时间越长,结果越长,越安全
md5_obj=hashlib.md5()#hashlib实例化
md5_obj.update('123'.encode('utf-8'))#将密码进行变形
print(md5_obj.hexdigest())#202cb962ac59075b964b07152d234b70
md5_obj=hashlib.md5()#hashlib实例化
md5_obj.update(''.encode('utf-8'))#将密码进行变形
print(md5_obj.hexdigest())#d41d8cd98f00b204e9800998ecf8427e 空内容也可以哈希
简单的登录练习
def login():
username=input('请输入你的账号:').strip()#xiaozhi
password=input('请输入你的密码:').strip()#123
md5_obj=hashlib.md5()#hashlib实例化
md5_obj.update(password.encode('utf_8')))#将密码进行变形
str_md5=md5_obj.hexdigest())#将密码进行加密
# print(str_md5)
with open('userinfo',encoding='utf-8')as f:
for line in f:
name,pwd=line.strip().split(',')#必须去空格
if name==username and pwd==str_md5:
print('恭喜你登录成功')
break
login()
sha算法
sha_obj=hashlib.sha1()
sha_obj.update('123'.encode('utf-8'))
str_sha=sha_obj.hexdigest()
print(str_sha,len(str_sha))#40位数的密码 40bd001563085fc35165329ea1ff5c5ecbdbbeef
# 密码加盐
md5_obj=hashlib.md5('糖'.encode('utf-8'))
md5_obj.update(b'123')
str_md5=md5_obj.hexdigest()
print(str_md5,len(str_md5))# 32位的密码 79c9808728cbae3d9c91984fdfc5a93d
def login():
username=input('请输入你的账号:').strip()#xiaoyang
password=input('请输入你的密码:').strip()#123
md5_obj=hashlib.md5('糖'.encode('utf-8'))#往密码里加了一个糖
md5_obj.update(password.encode('utf-8'))#将密码摘要
str_md5=md5_obj.hexdigest()#将密码加密
# print(str_md5)
with open('userinfo')as f:
for line in f:
name,pwd=line.strip().split(',')
if name==username and pwd==str_md5:
print('恭喜你登录成功')
break
login()
恶意注册 500个 可以试出简单的密码
动态加盐
每个用户的密码的密文的盐都不一样,例如,用name做盐
import hashlib
def login():
username=input('请输入你的账号:').strip()#xiaoli
password=input('请输入你的密码:').strip()#123
md5_obj=hashlib.md5(username.encode('utf-8'))#往密码里加了一个username的盐,变成动态加密
md5_obj.update(password.encode('utf-8'))#将密码摘要
str_md5=md5_obj.hexdigest()#将密码加密
# print(str_md5)
with open('userinfo')as f:#要注意把加密后的密码放到文件中
for line in f:
name,pwd=line.strip().split(',')
if name==username and pwd==str_md5:
print('恭喜你登录成功')
break
login()
md5的第一个功能--登录验证
sha系列和md5的用法相同
摘要算法的漏洞--撞库
加盐的摘要算法--恶意注册
动态加盐的摘要算法--完美
md5的第二个功能--校验文件的一致性
import os#和路径相关的问题,用os模块
with open(r'D:\untitled3\day22\userinfo',encoding='utf-8')as f:#不要引用当前文件的内容,下面执行相同代码时算出的值会不样。
file_size=os.path.getsize(r'D:\untitled3\day22\userinfo')#返回文件的大小
md5_obj=hashlib.md5()
while file_size>0:
str_content=f.read(1024)
md5_obj.update(str_content.encode('utf-8'))
file_size-=1024
str_md5=md5_obj.hexdigest()
print(str_md5)#
def size(a):#
with open(a, encoding='utf-8')as f:
file_size = os.path.getsize(a)
md5_obj1 = hashlib.md5()
for line in f:
md5_obj1.update(line.encode('utf-8'))
str_md5 = md5_obj1.hexdigest()
return str_md5 #
print(size(r'D:\untitled3\day22\userinfo'))
校验文件的一致性:md5速度快
logging模块
****会调用就行,不要求背
写日志的模块
在代码遇到问题的时候 —— 写给程序员看的
一些中间结果起到的排错作用
需要打印出来 —— 在排错的过程中
在真正提供服务的时候 —— 不需要
记录一些用户的行为 —— 写给用户看的
—— 写给公司看的
记录一个字符串
写文件 print
logging模块???
格式规范
帮你把日志的紧急情况进行分类
import logging
logging.debug('debug message') # 调试的时候
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message') # 批判的,比报错更严重
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
filename = 'test.log' )
logging.debug('debug message') # 调试的时候
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message') # 批判的
使用logger对象的形式进行配置
import logging
logger = logging.getLogger()
# 人
fmt = logging.Formatter('%(asctime)s -%(filename)s- %(name)s - %(levelname)s - %(message)s') # 格式
# 人 —— 练会了吸星大法
fh = logging.FileHandler('log',encoding='utf-8') # 创建了一个文件操作符
fh.setFormatter(fmt) #给文件操作符设置一个格式
logger.addHandler(fh) # 给logger对象添加fh武功
在屏幕上输入
sh = logging.StreamHandler()
sh.setFormatter(fmt)
sh.setLevel(logging.WARNING)
logger.addHandler(sh)
# logging.StreamHandler() # 创建了一个屏幕操作符
logger.setLevel(logging.DEBUG)
logger.debug('debug message') # 调试的时候
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message') # 批判的
注意事项
在哪一行 写了 logger.debug('>>>>>')
configparser模块
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('example.ini', 'w') as f:
config.write(f)
import configparser
config = configparser.ConfigParser()
print(config.sections()) # []
config.read('example.ini')
print(config.sections()) # ['bitbucket.org', 'topsecret.server.com']
print('bytebong.com' in config) # False
print('bitbucket.org' in config) # True
print(config['bitbucket.org']["user"]) # hg
print(config['DEFAULT']['Compression']) #yes
print(config['topsecret.server.com']['ForwardX11']) #no
print(config['bitbucket.org']) #<Section: bitbucket.org>
for key in config['bitbucket.org']: # 注意,有default会默认default的键
print(key)
print(config.options('bitbucket.org')) # 同for循环,找到'bitbucket.org'下所有键
print(config.items('bitbucket.org')) #找到'bitbucket.org'下所有键值对
print(config.get('bitbucket.org','compression')) # yes get方法Section下的key对应的value
tast
有两个文件作为参数
判断这两个文件是否相同,如果相同,返回True,否则返回False
import os
import hashlib
def consistency(a,b):
with open(a, encoding='utf-8')as f1:
md5_obj = hashlib.md5()
for line in f1:
md5_obj.update(line.encode('utf-8'))
str_md5 = md5_obj.hexdigest()
# return str_md5 #函数中间不能用return,否则就打断循环了
with open(b, encoding='utf-8')as f2:
md5_obj1 = hashlib.md5()
for line in f2:
md5_obj1.update(line.encode('utf-8'))
str_md51 = md5_obj1.hexdigest()
if str_md51==str_md5:
return True
else:
return False
print(consistency('userinfo','复习'))#'userinfo','复习'

浙公网安备 33010602011771号