Python 的 hashlib 提供了常见的摘要算法,如 MD5,SHA1
等等,摘要算法又称哈希算法,散列算法,该算法通过一个函数,把任意长度的数据转换为一个长度固定的数据串。
比如我们在网上发送信函,以防止内容被篡改,可以对其进行摘要算法,然后对比发送前后的摘要算法的结果是否一致。
比如我们对应用程序进行升级,以防止升级的内容被篡改,或者丢失等等,我们可以对升级后的程序文件进行摘要算法来判断它的完整性和正确性。
使用 hashlib
使用 hashlib 模块的摘要算法 md5 函数计算一个数据内容的 md5
值,注意:无论被计算的数据有多大,计算出来的 md5 值的长度都是 32
位长度的字符。
import hashlib mystr = "python".encode("utf8") md5 = hashlib.md5() md5.update(mystr) mystrmd5 = md5.hexdigest() # 对 mystr 进行 md5 运算 print(len(mystrmd5)) # 32 mystrxx = "我爱python,啦啦啦".encode("utf8") md5xx = hashlib.md5() md5xx.update(mystrxx) mystrxxmd5 = md5xx.hexdigest() # 对 mystrxx 进行 md5 运算 print(len(mystrxxmd5)) # 32
比如我们在网上发送信函,以防止内容被篡改,可以对其进行摘要算法,对比发送前后的摘要算法的结果是否一致。
import hashlib mystr = "python".encode("utf8") # 这是我们的信件内容 md5 = hashlib.md5() md5.update(mystr) mystrmd5 = md5.hexdigest() # 我们把信件内容 mystr,和信件的 md5 一块通过网络发送给对方 ################## 对方收到信件内容后 ################## mystrxx = "Python".encode("utf8") # 我们收到的信件内容,假定小写字母 p 被网络黑客篡改为大写字母 P md5xx = hashlib.md5() md5xx.update(mystrxx) mystrxxmd5 = md5xx.hexdigest() if mystrmd5 != mystrxxmd5: print("风险警告:内容被篡改") else: print("收到正确的信件内容")
我们可以对任何文件计算其 md5 值,同样我们也可以对图片计算 md5,来判断其完整性和正确性。
比如下面两张图片,我们肉眼看不出来任何差别,实际上我在第二张图片如花的头发出点了一个黑点。
from urllib import request import ssl import hashlib context = ssl._create_unverified_context() ruhuaurl_one = "https://www.birdpython.com/static/img/python3-lession/12/12-1-1.png" rst = request.urlopen(ruhuaurl_one, context=context) ruhuaimg_one = rst.read() # 第 1 张如花图片的数据 ruhuaurl_two = "https://www.birdpython.com/static/img/python3-lession/12/12-1-2.png" rst = request.urlopen(ruhuaurl_two, context=context) ruhuaimg_two = rst.read() # 第 2 张如花图片的数据 md5one = hashlib.md5() md5one.update(ruhuaimg_one) ruhuaimg_one_md5 = md5one.hexdigest() # 第 1 张如花图片的 md5 md5two = hashlib.md5() md5two.update(ruhuaimg_two) ruhuaimg_two_md5 = md5two.hexdigest() # 第 2 张如花图片的 md5 if ruhuaimg_one_md5 != ruhuaimg_two_md5: print("两张图片不一样") else: print("两张图片一样")
比如我们对应用程序进行升级,升级的文件很多(好几个 G),我们想一下子对所有文件计算出 md5,
就需要读入几个 G 文件到内存,可能会撑爆内存,这样显然是很 low 的方法。
对于这种数据量很大,我们可以分块多次调用 update,来对比最后计算的结果是不是一样的。
import hashlib mystr = "我是python网站的图片...巴拉巴拉...".encode("utf8") # 假设这是升级的文件 a mystrtwo = "我是python网站的视频...巴拉巴拉...".encode("utf8") # 假设这是升级的文件 b md5 = hashlib.md5() md5.update(mystr) md5.update(mystrtwo) mystrmd5 = md5.hexdigest() # 文件 a 和 文件 b 的 md5 print(mystrmd5)
注意:md5 的意义所在,主要用于防篡改,也就是校验文件的一致性,我们不建议用作加密使用(因为无法通过摘要反推明文)。
但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。
本节重要知识点
会使用 md5 模块。
弄明白 md5 使用的场景,不要作为数据加密使用。