算法介绍:
Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。
什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。
摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。
摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。
hashlib:摘要算法
一般摘要
加盐摘要
动态加盐摘要
#一般摘要
import hashlib
md = hashlib.md5() #获取一个以md摘要的对象
md.update(b'1234') #update方法,传入需要摘要的字符串,必须为bytes类型
#md.update(bytes(password,encoding='utf-8')) #password为动态字符串,同样需要转换为bytes类型,指定字符编码
ret = md.hexdigest #hexdigest是hashlib的一个方法,指向的是存有摘要值的内存地址
ret = md.hexdigest() #加上()获取摘要后的值
#如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:
md5 = hashlib.md5()
md = hashlib.md5()
md5.update('how to use md5 in ')
md5.update('python hashlib?')
md.update('how to use md5 in python hashlib?')
print(md5.hexdigest())
print(md.hexdigest())
#打印:
d26a53750bc40b38b65a520292f69306
d26a53750bc40b38b65a520292f69306
注意: md5是hashlib模块中的一个类,属于一种算法。还有sha1,sha224等算法。update属于算法的方法,用于传入需要摘要的参数。hexdigest是hashlib的一个方法,用于获取摘要后的值。如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的
加盐摘要:
hashlib.md5(盐)
md = hashlib.md5(b'aike')#b,默认为ASCII码,不支持中文
md1 = hashlib.md5(bytes('艾克',encoding='utf-8'))#中文需要用bytes方式制定编码
md.update(b'1234')
md1.update(b'1234')
ret = md.hexdigest()
ret1 = md1.hexdigest()
print(ret)
print(ret1)
动态加盐:
usr = input('请输入用户名')
md = hashlib.md5(b'aike')#b,默认为ASCII码,不支持中文
md1 = hashlib.md5(bytes('艾克',encoding='utf-8')+bytes(usr,encoding='utf-8'))#接收动态的参数进行加盐
md.update(b'1234')
md1.update(b'1234')
ret = md.hexdigest()
ret1 = md1.hexdigest()
print(ret)
print(ret1)
应用:存储用户登录的用户名和口令
#注册
def info():
try:
info_usr = True
while info_usr:
f = open('user_data','a+',encoding='utf-8') #以with形式
f.seek(0)#a+形式打开文件,若想遍历文件内容,需要把光标位置移到开头
for line in f:
username = input('请输入用户名:')
password = input('请输入密码:')
usr,pwd = line.split('|')
if usr.strip() == username.strip():
print('账户已被注册,请重新输入')
else:
md5 = hashlib.md5()
md5.update(bytes(password,encoding='utf-8'))
info_password = md5.hexdigest()
f.write(username+'|')
f.write('%s\n'%info_password)
info_usr = False
f.close()
except ValueError: #关闭文件后抛出异常提示注册成功
print('注册成功')
#登录
def longin():
i = 3
while i > 0:
i -= 1
with open('user_data') as f:
username = input('请输入用户名:')
password = input('请输入密码:')
for line in f:
md5 = hashlib.md5()
md5.update(bytes(password,encoding='utf-8'))
info_password = md5.hexdigest()
usr,pwd = line.strip().split('|')
if usr.strip() == username and pwd.strip() == info_password:
print('登录成功')
break
else:
print('登录失败,请重新登录,还有%s次机会'%i)
else:
print('账户已锁定')
# 测试
lis = [
'登录',
'注册'
]
for i in enumerate(lis):
print(i)
while True:
try:
select = int(input('请输入序号选择登录或者注册:'))
if select == 0:
longin()
break
elif select == 1:
info()
break
else:
print('请输入正确的序列号')
except Exception:
print('请输入正确的序列号')
知识点: hashlib
异常处理
文件读写
bug:由于是以文件形式存取账户名与密码,只能验证最后一行用户名与密码