news 2026/9/10 14:41:10

Python进阶教程:18_hashlib 模块 零基础超详细教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python进阶教程:18_hashlib 模块 零基础超详细教程

hashlib是 Python 内置的哈希(散列)计算标准库,不需要额外安装,可以快速生成文本、文件的「哈希摘要」(也叫散列值、指纹)。它是密码存储、文件完整性校验、数据去重、防篡改等功能的底层基础,也是新手进阶必学的工具模块。

本文从最基础的「哈希是什么」讲起,全程配可运行代码 + 逐行解释 + 新手避坑指南,零基础也能完全吃透。


一、前置必懂:什么是哈希?

1. 通俗理解:哈希 = 数字指纹

你可以把哈希算法理解成一台「指纹生成机」:

  • 输入:任意长度的数据(一段文字、一个文件、一张图片)
  • 输出:固定长度的字符串(比如 32 位、64 位),就是这个数据的「哈希摘要 / 指纹」

就像每个人的指纹都是唯一的,只要原始数据有一点点改动,生成的指纹就会完全不同;相同的输入,永远会得到相同的指纹。

2. 哈希算法的四大核心特点

这四个特点是所有哈希应用的基础,新手一定要记牢:

  1. 单向不可逆:只能从原始数据算出哈希值,绝对不能从哈希值反推出原始数据(和加密解密不一样,加密是可逆的)
  2. 长度固定:不管输入是 1 个字符还是 10GB 的文件,同一种算法输出的哈希值长度永远一样(比如 MD5 永远是 32 位十六进制字符串)
  3. 雪崩效应:原始数据哪怕只改一个字、一个标点,生成的哈希值都会天差地别,完全看不出关联
  4. 确定性:相同的输入、相同的算法,无论算多少次,结果永远一模一样

3. hashlib 模块能做什么

Python 的hashlib封装了所有主流哈希算法,帮我们快速计算哈希值,常见用途:

  • 文件完整性校验:下载软件 / 电影后,算 MD5 和官方对比,确认文件没被篡改、没下载损坏
  • 密码安全存储:数据库里不存明文密码,只存密码的哈希值,就算数据库泄露也拿不到原密码
  • 数据去重:给文件 / 内容算哈希,相同内容哈希一样,通过哈希快速判断重复
  • 防篡改:接口签名、数据校验,确认数据传输过程中没被修改

二、基础使用:通用三步法

所有哈希算法的使用流程完全一致,记住三步即可:

  1. 创建哈希对象:选择算法,初始化一个计算对象
  2. 喂入数据:把要计算的二进制数据传进去(可以分批喂)
  3. 获取结果:生成最终的哈希摘要

1. 第一个入门例子:计算字符串的 MD5

# 1. 导入内置模块,无需安装 import hashlib # 2. 创建MD5算法的哈希对象 md5_obj = hashlib.md5() # 3. 喂入数据:必须传 bytes 字节类型,字符串要先用 encode 转成字节 # 重点:哈希是对二进制数据计算的,字符串不能直接传 text = "Hello Python" md5_obj.update(text.encode("utf-8")) # 4. 获取最终哈希摘要:hexdigest() 返回十六进制字符串(最常用) result = md5_obj.hexdigest() print(f"原始字符串:{text}") print(f"MD5 哈希值:{result}")

运行结果:

原始字符串:Hello Python MD5 哈希值:a709c173228d32d242b7e38913a774a9

逐行解释

  • hashlib.md5():创建一个专门用来算 MD5 的计算对象,类似准备好一台 MD5 指纹机
  • .encode("utf-8"):把字符串转成二进制字节,这是新手 100% 会踩的坑 ——hashlib 所有 update 都只能传字节,传字符串会直接报错
  • .update(数据):把数据喂给哈希对象,开始计算
  • .hexdigest():输出最终的哈希值,格式是十六进制字符串,也是日常开发最常用的输出格式

2. 两种输出摘要的方式

表格

方法返回类型特点适用场景
.hexdigest()十六进制字符串可读性好,由 0-9 和 a-f 组成绝大多数场景,存数据库、打印对比
.digest()bytes 字节串体积小,不可读网络传输、二进制存储

示例对比:

import hashlib md5_obj = hashlib.md5(b"test") # 也可以直接在创建时传初始数据 print("十六进制:", md5_obj.hexdigest()) # 098f6bcd4621d373cade4e832627b4f6 print("字节格式:", md5_obj.digest()) # b'\t\x8fk\xcdF!\xd3s\xca\xdeN\x83&\'\xb4\xf6'

3. 可以多次 update 分批喂数据

哈希支持增量计算:你可以分多次把数据喂进去,最终结果和一次性喂完全一样。这个特性非常重要,后面计算大文件会用到。

import hashlib md5_obj = hashlib.md5() # 分三次喂数据 md5_obj.update(b"Hello ") md5_obj.update(b"Python") # 结果和一次性喂"Hello Python"完全一样 print(md5_obj.hexdigest()) # a709c173228d32d242b7e38913a774a9

三、常用哈希算法 & 示例

hashlib支持十几种算法,新手掌握最常用的 3 类即可,不同算法只是创建对象的函数名不一样,使用流程完全相同。

1. MD5 算法

  • 输出长度:32 位十六进制字符串
  • 特点:计算速度极快、体积小;但安全性低,已经被破解,存在碰撞风险(不同数据可能算出相同 MD5)
  • 适用场景:非安全场景的文件完整性校验、普通数据去重,绝对不能用于密码、签名等安全场景
import hashlib def get_md5(text: str) -> str: """计算字符串的MD5值""" md5 = hashlib.md5(text.encode("utf-8")) return md5.hexdigest() print(get_md5("123456")) # e10adc3949ba59abbe56e057f20f883e

2. SHA-1 算法

  • 输出长度:40 位十六进制字符串
  • 特点:比 MD5 稍慢,安全性也已经被攻破,不推荐用于安全场景
  • 适用场景:旧系统兼容、普通文件校验
import hashlib sha1 = hashlib.sha1(b"Hello Python") print("SHA1值:", sha1.hexdigest()) # 输出:6b0d92ce83a04c7c40c57f9d9a3e0a3c2d7e3f0b

3. SHA-2 系列(主流安全选择)

这是目前最主流、最安全的通用哈希算法,安全场景优先用这个系列,最常用的是 SHA256。

  • SHA256:输出 64 位十六进制,安全性高、速度适中,绝大多数安全场景的首选
  • SHA512:输出 128 位十六进制,安全性更高,速度稍慢,对安全要求极高的场景使用
SHA256 示例
import hashlib def get_sha256(text: str) -> str: """计算字符串的SHA256值""" sha256 = hashlib.sha256(text.encode("utf-8")) return sha256.hexdigest() print(get_sha256("123456")) # 输出:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92

算法对比总结表

算法输出长度(十六进制)速度安全性推荐用途
MD532 位极快低,已破解普通文件校验、非安全去重
SHA140 位低,已破解旧系统兼容、非安全校验
SHA25664 位中等接口签名、防篡改、安全校验
SHA512128 位稍慢极高高安全级别的签名、校验

💡 新手选型建议:

  • 只是做文件完整性、去重,追求速度 → 用 MD5
  • 涉及安全、防篡改、签名 → 直接用 SHA256,不用纠结
  • 存密码 → 都不要用,后面会讲原因和正确方案

四、核心特性演示:雪崩效应

哈希最经典的特性:原始数据哪怕只改一个字符,哈希值都会完全不一样,像雪崩一样。我们用代码直观验证一下:

import hashlib text1 = "今天天气真好" text2 = "今天天气真不好" # 只多了一个"不"字 md5_1 = hashlib.md5(text1.encode()).hexdigest() md5_2 = hashlib.md5(text2.encode()).hexdigest() print(f"原文1:{text1}") print(f"MD5:{md5_1}") print("-"*50) print(f"原文2:{text2}") print(f"MD5:{md5_2}")

运行结果:

原文1:今天天气真好 MD5:a1b2c3...(示例) -------------------------------------------------- 原文2:今天天气真不好 MD5:x9y8z7...(示例)

可以看到,只差了一个字,两个 MD5 没有任何相似之处,完全无法通过哈希值猜测原文的差异。这也是哈希能用来判断数据是否被篡改的核心原理。


五、进阶实战:计算大文件的哈希

计算小字符串可以一次性 encode,但如果是几个 GB 的大文件,一次性读进内存会直接导致内存溢出。这时候就要用到「分块读取 + 多次 update」的方式,边读边算,内存占用极低。

完整示例:计算文件的 MD5

import hashlib def get_file_md5(file_path: str) -> str: """ 计算大文件的MD5值,分块读取,不占内存 :param file_path: 文件路径 :return: MD5十六进制字符串 """ md5_obj = hashlib.md5() # 以二进制只读模式打开文件 with open(file_path, "rb") as f: # 每次读取 4KB 数据,循环读完整个文件 while True: chunk = f.read(4096) # 4096字节 = 4KB # 读完了就退出循环 if not chunk: break # 分批喂入哈希对象 md5_obj.update(chunk) return md5_obj.hexdigest() # 使用示例:计算当前目录下 test.txt 的MD5 if __name__ == "__main__": md5 = get_file_md5("test.txt") print(f"文件MD5:{md5}")

代码解释

  1. open(file_path, "rb"):必须用二进制模式rb打开文件,读出来的直接是字节,不需要再转码
  2. f.read(4096):每次只读 4KB,无论文件多大,内存永远只占 4KB,非常高效
  3. 循环读完所有块,每次都update,最终结果和一次性读完整文件计算完全一致

💡 拓展:想算 SHA256 只需要把hashlib.md5()改成hashlib.sha256(),其他代码完全不用动。


六、经典应用场景实战

场景 1:文件完整性校验

下载文件后,对比官方给出的哈希值,确认文件没有损坏、没有被植入病毒。

import hashlib # 官方给出的正确MD5 official_md5 = "a1b2c3d4..." # 计算你下载的文件的MD5 your_file_md5 = get_file_md5("下载的安装包.exe") if your_file_md5 == official_md5: print("文件完整,没有被篡改") else: print("文件可能损坏或被篡改,请重新下载")

场景 2:密码加盐哈希(原理演示)

很多新手会直接把密码的 MD5 存进数据库,这是非常危险的!

  • 问题:简单密码的 MD5 可以通过「彩虹表」反查出来,比如123456的 MD5 全网都能查到
  • 解决方法:加盐(salt)—— 给密码拼接一段随机字符串,再算哈希,大幅提升破解难度
加盐哈希示例
import hashlib import uuid def hash_password(password: str, salt: str = None) -> tuple[str, str]: """ 给密码加盐生成哈希 :param password: 原始密码 :param salt: 盐,不传就自动生成随机盐 :return: (哈希值, 盐) """ # 生成随机盐:用uuid生成唯一随机字符串 if salt is None: salt = uuid.uuid4().hex # 32位随机十六进制字符串 # 密码 + 盐 拼接后算SHA256 sha256 = hashlib.sha256((password + salt).encode("utf-8")) password_hash = sha256.hexdigest() return password_hash, salt # ========== 注册时:生成哈希和盐,一起存进数据库 ========== pwd = "123456" pwd_hash, salt = hash_password(pwd) print(f"存储到数据库的哈希:{pwd_hash}") print(f"存储到数据库的盐:{salt}") # ========== 登录时:用同样的盐计算,对比结果 ========== def verify_password(input_pwd: str, saved_hash: str, saved_salt: str) -> bool: """验证密码是否正确""" # 用用户输入的密码 + 存好的盐,重新算哈希 calc_hash, _ = hash_password(input_pwd, saved_salt) # 和数据库里存的哈希对比 return calc_hash == saved_hash # 测试:输入正确密码 print(verify_password("123456", pwd_hash, salt)) # True # 测试:输入错误密码 print(verify_password("1234567", pwd_hash, salt)) # False

⚠️ 非常重要的新手提醒: 上面只是原理演示!真实生产环境不要自己用 hashlib 写密码加密。 因为 MD5、SHA256 都是快哈希算法,计算速度太快,黑客可以每秒试几十亿次密码,暴力破解成本很低。 真正存密码请用专门的「慢哈希库」,比如bcryptargon2-cffi,它们会故意放慢计算速度,大幅提升暴力破解成本。

场景 3:批量文件去重

给每个文件算哈希,相同文件哈希一定一样,通过哈希快速找出重复文件:

import os import hashlib def find_duplicate_files(folder_path: str) -> dict: """找出文件夹里的重复文件""" hash_map = {} # key: 文件哈希, value: 文件路径列表 for root, _, files in os.walk(folder_path): for file in files: file_path = os.path.join(root, file) file_md5 = get_file_md5(file_path) if file_md5 in hash_map: hash_map[file_md5].append(file_path) else: hash_map[file_md5] = [file_path] # 只返回有重复的 return {k: v for k, v in hash_map.items() if len(v) > 1}

七、新手高频易错点总结

1. 直接传字符串报错

update()只能接收bytes字节类型,传字符串会报TypeError: Unicode-objects must be encoded before hashing。 ✅ 解决:字符串用.encode("utf-8")转成字节再传。

2. 以为哈希可以解密

哈希是单向的,只能正向计算,不能反向解密。网上所谓的「MD5 解密」都是彩虹表查询,本质是提前存好海量密码和对应的 MD5,碰运气匹配,不是真的解密。

3. 用 MD5 存密码

MD5 速度太快,容易被暴力破解,哪怕加了盐也不推荐用于密码存储。生产环境请使用专门的密码哈希库。

4. 大文件一次性读取

计算大文件哈希时不要一次性读进内存,一定要分块循环读取,避免内存溢出。

5. 混淆十六进制和字节摘要

日常打印、存数据库、对比都用hexdigest()的字符串格式;digest()只用于特殊的二进制传输场景。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 3:04:09

还原结束后的六项检查,少一项都别交业务

数据库进程启动、端口可连,只能说明还原进入了可检查阶段。恢复点可能错了,业务账号可能无权,序列可能落后,统计信息可能缺失,归档和备份任务也可能仍指向旧环境。此时直接开放流量,问题会从恢复现场扩散到…

作者头像 李华
网站建设 2026/9/3 3:53:26

贝壳找房春招笔试解析:数据挖掘与机器学习核心考点实战

每年春招这个时间点,贝壳找房的算法岗笔试题总能在圈子里引起一波讨论。它不像互联网大厂那样疯狂堆砌LeetCode hard题,也不像某些实验室风格团队那样只考论文复现,贝壳的题目风格更偏向“业务落地”——给你一堆现实世界里的脏数据&#xff…

作者头像 李华
网站建设 2026/9/3 2:17:29

BentoDiffusion实战:基于BentoML的扩散模型服务化部署指南

这次我们来看一个非常实用的开源项目:bentoml/BentoDiffusion。如果你接触过 Stable Diffusion 这类扩散模型,一定知道“本地能跑起来”和“能稳定对外提供服务”是两回事。单机写个 Python 脚本生成图片很容易,但一旦涉及多模型管理、接口暴…

作者头像 李华
网站建设 2026/9/5 13:07:48

Python+MySQL图书管理系统开发实战:从数据库设计到GUI实现

简介:本资源是一套完整的Python课程设计项目——基于tkinter与MySQL开发的图书管理系统,面向计算机类专业本科生及初学者,解决课程大作业、毕业设计选题与GUI数据库实战练习需求。压缩包共13个文件(6个Python源码模块、4个配置/日…

作者头像 李华
网站建设 2026/9/3 1:02:03

2026年7月驻马店市新房价格深度分析报告

一、报告背景与数据说明本报告基于2026年7月驻马店市新房实际成交案例,结合网签备案数据、售楼处成交记录及市场调研信息,对驻马店市中心城区及重点县区的新房价格水平、成交结构、价格走势及区域分化特征进行深度分析。报告旨在为购房者、开发商及研究机…

作者头像 李华