20. hashlib模块
一、模块如何使用
- 在Python中引用hashlib模块
- 创建一个hash对象,使用hash算法命名的构造函数,或者通用构造函数
- 使用hash对象调用update()方法填充对象
- 调用digest()或者hexdigest()方法来获取摘要(加密结果)
二、模块实际使用
1. md5_obj = hashlib.md5() 或 md5_obj = hashlib.new("md5") -> md5可以替换为其他的哈希类型
2. md5.update(arg) -> 将字节对象arg填充到hashlib对象中,arg通常为要加密的字符串
3. md5.digest() -> 返回加密结果 ,它是一个字节对象,长度为md5.digest_size
4. md5.hexdigest() -> 返回加密结果,它是一个字符串对象,长度为md5.digest_size*2,只包含16进制数字
注意事项:
(1) update()方法需要接收的参数是一个字节对象
(2) 常用的一些算法主要有sha1, sha224, sha256, sha384, sha512, md5等算法
(3) sha1算法比较早,是不能暴力破解的
import hashlib
Plaintext = "Hello world"
# 实例化一个hash对象
md5_obj = hashlib.md5()
# 对需要操作的明文操作->编程16进制
result = md5_obj.hexdigest()
print(result)
>d41d8cd98f00b204e9800998ecf8427e
加盐 - hashlib.md5("salt".encode("utf-8"))
import hashlib
# md5_obj = hashlib.md5(b"with salt")
md5_obj = hashlib.md5("with salt".encode("utf-8"))
md5_obj.update("hello world".encode("utf-8"))
result = md5_obj.hexdigest()
print(result)
1. 示例一
在用户登陆验证时,通常将用户账号与密码存入文件中,而用户密码不是原样保存在文件中,而实通过一些转换手段,这里使用md5算法,根据其优点不可逆转推导,因此,一般不容易破解得到用户密码。
import hashlib
def get_md5(Plaintext):
md5_obj = hashlib.md5()
md5_obj.update(Plaintext.encode("utf-8"))
result = md5_obj.hexdigest()
return result
username = input("username:")
password = input("password:")
with open("userInfo") as f:
for line in f:
usr, pwd = line.strip().split('|')
if username == usr and get_md5(password) == pwd:
print("登录成功!")
break
else:
print("登录失败!")
2. 示例二
读取文件时,最好不用f.readline()。原因:将文件内容全部读入内存,使得内存占用资源变大,从而浪费资源。故建议使用for循环对文件句柄操作,对文件内部内容逐行读取
import hashlib
def get_file_md5(file_path):
md5_obj = hashlib.md5()
with open('file_path', encoding = 'utf-8') as f:
for line in f:
md5_obj.update(line.encode('utf-8'))
ret = md5_obj.hexdigest()
return ret
3. 示例三
上面介绍文件其所占的字节较少,如果下载的是视频或者大文件,此时,读取的形式应该以rb形式,读出来的都是bytes,此外,类似视频这样的文件,不能按行来读取,也不能一次性读取出来 - 使用getsize()方法,每次对视频或者大文件取固定字节
import os
import hashlib
def get_file_md5(file_path, buffer = 1024):
md5_obj = hashlib.md5()
file_size = os.path.getsize(file_path)
with open(file_path, 'rb') as f:
while file_size:
content = f.read(buffer)
file_size -= len(content)
md5_obj.update(content) # 文件是rb形式传输,所以不需要'utf-8'
return md5_obj.hexdigest()
4. 示例四
import hashlib
def md5(arg): # 这是加密函数,将传进来的函数加密
md5_pwd = hashlib.md5(bytes("abd", encoding="utf-8"))
md5_pwd.update(bytes(arg, encoding="utf-8"))
return md5_pwd.hexdigest() # 返回加密的数据
def log(user, pwd): # 登录时候的函数,由于md5不能反解, 因此登录的时候用正解
with open("user.txt", mode="r", encoding="utf-8") as f:
for line in f:
name, password = line.strip().split("|")
# 登录的时候验证用户名以及加密的密码跟之前保存的是否一样
if user == name and password == md5(pwd):
return True
def register(user, pwd): # 注册的时候把用户名和加密的密码写进文件,保存起来
with open("user.txt", mode="a", encoding="utf-8") as f:
msg = user + "|" + md5(pwd) + "\n"
f.write(msg)
i = input("1表示登录,2表示注册").strip()
if i == "2":
user = input("用户名:")
pwd = input("密码:")
register(user, pwd)
elif i == "1":
user = input("用户名")
pwd = input("密码:")
r = log(user, pwd) # 验证用户名和密码
if r == True:
print("登录成功")
else:
print("登录失败")
else:
print("输入不合法")