#️⃣ 哈希函数入门
把"任意长度内容"压成"固定长度摘要" · 校验 / 密码存储 / 哈希表 / 数字签名
🎯学习目标
读完这一讲,你应该能回答:
- 一句话说清哈希函数是什么?(任意长 → 定长摘要 / 短指纹)
- 分清哈希、加密、编码三者的区别。
- 好哈希函数的 5 个特性是什么?
- 哈希的 4 大用途(完整性校验 / 密码存储 / 哈希表 / 底层积木)。
- 避开 3 个常见误区,记住 5 句话总结。
1一句话理解:把任意内容压成固定长度摘要
💡 一句话
哈希函数把"任意长度的内容"压成"固定长度的摘要"。摘要是内容的"短指纹",但不是原文本身。
图1 · 不管原始内容多长,摘要长度都固定(SHA-256 始终 256 位)
日常说的"哈希值""摘要""digest",通常就指这串短结果。同样输入 → 同样摘要;只改一点 → 摘要大变。
2别和"加密""编码"混淆 ⭐
这三个概念最容易搞混,一定要分清——一眼区分:哈希偏"摘要与校验",加密偏"保密",编码偏"换一种表示"。
#️⃣
哈希
原文 → 摘要
可逆性:通常不可逆
目的:校验 / 索引
SHA-256
🔒
加密
原文 →(有密钥)→ 密文
可逆性:有密钥可逆
目的:保密
AES · RSA
🔁
编码
数据 → 另一种表示
可逆性:完全可还原
目的:表示转换
Base64 · UTF-8
| 哈希 | 加密 | 编码 | |
|---|---|---|---|
| 输入→输出 | 原文→摘要 | 原文→密文 | 数据→另一种表示 |
| 可逆性 | 通常不可逆 | 有密钥可逆 | 完全可还原 |
| 目的 | 校验 / 索引 | 保密 | 表示转换 |
| 例子 | SHA-256 | AES、RSA | Base64、UTF-8 |
⚠️ 最常见的误解
想把内容"藏起来"时去用哈希。正确做法:需要保密用加密;需要验证内容用哈希;只是换表示用编码。
🎮 小练习:把需求和正确做法连起来
先点左边一个需求,再点右边对应的做法。连对会变绿。
📌 需求
把内容藏起来不让别人看
验证文件有没有被改
把二进制变成可传输文本
🎯 正确做法
编码(Base64)
加密(AES/RSA)
哈希(SHA-256)
3好哈希函数的 5 个特性 ⭐
本科阶段先记住 5 个关键词:定长、确定、快速、雪崩、难逆推/难碰撞(原文按"任意长输入、定长输出、确定、雪崩、难逆推难碰撞"列)。
📥
1 任意长度输入
一篇论文和一串学号都能哈希📏
2 固定长度输出
如 SHA-256 始终输出 256 位🎯
3 确定性
同样输入→同样输出,否则无法比较/定位❄️
4 雪崩效应
输入改一点→摘要大变,便于发现篡改🛡️
5 难逆推/难碰撞
安全场景必需❄️ 雪崩效应:只改一个字符,摘要完全不同
输入 A:OpenAI-2025
→ d7fa28287222217a…
输入 B:OpenAI-2026
→ 2b10233e76f1f365…
💡 为什么重要?
雪崩效应让"内容只改一点点,校验值就显著不同",从而能可靠地发现文件损坏或篡改。
4用途 1:完整性校验——检查"内容有没有变"
哈希最朴素、也最常见的用途:下载、传输、备份、版本发布时做完整性验证。
图2 · 完整性校验流程:两边摘要一致说明内容没变
- 发布方先公布:文件 + 摘要(如 SHA-256)。
- 接收方下载后,对同一文件再算一次哈希。
- 两边摘要一致 → 未变;不一致 → 可能损坏或被篡改。
例如 课件_v1.pdf → 363b8eae…,文件名只改一个字母 课件_v1.pdg → ada327c9…,摘要就显著不同。
📌 要点
哈希负责"验有没有变",不是"把原文藏起来"。
5用途 2:密码存储——服务器不该保存明文密码 ⭐
正确姿势:带盐(salt),并使用专门的"慢哈希 / 自适应哈希"算法,而不是把密码原样存进数据库。
图3 · 密码存储:密码+盐 → 慢哈希 → 数据库只存 salt+hash(不是明文)
🔑 登录时怎么验证?
用户重新输入密码 → 系统取出该用户的 salt → 用同样算法再算一次 → 只比较 hash 是否一致。
✗ 别这么做
✗ 明文存密码;✗ 只用普通快速哈希(如直接 MD5)存密码。
推荐:Argon2id(带盐的慢哈希);没有时再考虑 bcrypt / scrypt。
推荐:Argon2id(带盐的慢哈希);没有时再考虑 bcrypt / scrypt。
💡 为什么要"慢哈希"+"加盐"?
慢哈希让暴力破解变慢;加盐让攻击者无法用预先算好的"彩虹表"批量破解。
6用途 3:哈希表——把"找东西"变快
在数据结构里,哈希函数把 key 映射到数组槽位;平均情况下,插入与查找都很快。
图4 · 哈希表:hash(学号) → 槽位 3 → 直接定位"张三记录"
⚠️ 碰撞(Collision)
如果两个 key 落到同一槽位,就叫碰撞。系统需要用拉链法、开放寻址等方法继续处理。平均情况查找很快;坏情况(碰撞多)会拖慢。
一句话总结:哈希函数让"从 key 找到数据"通常不必从头扫完整个列表。
7用途 4:很多安全系统的底层积木
把大对象先压成短摘要,能让"签名、命名、链接结构"都更高效。共同点:先压缩,再验证 / 定位 / 链接。
✍️
数字签名
先对长消息取哈希,再对摘要签名;更快、适合大文件🌿
Git / 内容寻址
对象内容一变,哈希名就变,能精确定位对象🌳
Merkle 树 / 区块链
底层任一叶子改动,整条向上的哈希都变化,便于整体校验🧱
底层积木
先压缩再验证/定位/链接,是各类系统的通用套路图5 · Merkle 树:底层叶子先各自取哈希,再逐层汇总到根哈希
8三个常见误区(别把哈希想成"万能胶")
❌ 误区 1:"哈希 = 加密"
纠正:哈希通常不可逆,主要做摘要与验证;需要保密时应使用加密。
❌ 误区 2:"摘要相同绝不可能发生"
纠正:输出空间有限,碰撞在理论上必然存在;目标是让它"极难找到",而非绝不可能。
❌ 误区 3:"任何 hash 都适合安全场景"
纠正:SHA-1 已不安全,新的抗碰撞设计不要再用;密码存储也不该直接用普通快速哈希。
图6 · 碰撞不是"绝不可能",而应"在现实中极难构造"
9带走这 5 句话
- 哈希函数把任意长度输入压成固定长度摘要。
- 同样输入得同样输出;改一点,摘要大变(雪崩)。
- 验文件完整性,优先想到 SHA-256 这类安全哈希。
- 存密码,要用带盐的 Argon2id / bcrypt / scrypt,而不是明文或普通快速哈希。
- 想保密用加密;想快速按 key 查找想到哈希表。
场景 → 首选思路
| 场景 | 首选 |
|---|---|
| 文件有没有变 | SHA-256 等安全哈希 |
| 密码怎么存 | Argon2id / bcrypt / scrypt(带盐慢哈希) |
| 字典/索引怎么快查 | 哈希表 |
| 内容要保密 | 加密(不是哈希) |
🎯 一句话收尾
哈希函数是计算机世界里的"短指纹"——擅长校验、索引和链接结构,但不负责替代加密。
🔗 关联 CH4 数据完整性 / 数字签名 🔗 关联 CH5 口令加盐鉴别
🎯自测(点击展开参考要点)
一句话说清哈希函数是什么?
把任意长度的内容压成固定长度的摘要(短指纹),通常不可逆,主要用于校验、索引、链接结构。
哈希、加密、编码三者的核心区别?
哈希:原文→摘要,通常不可逆,做校验/索引;加密:原文→密文,有密钥可逆,做保密;编码:换一种表示,完全可还原(如Base64/UTF-8)。
好哈希函数有哪 5 个特性?
任意长度输入、固定长度输出、确定性(同输入同输出)、雪崩效应(改一点摘要大变)、难逆推/难碰撞。
密码存储为什么要"加盐 + 慢哈希"?
慢哈希(Argon2id/bcrypt/scrypt)让暴力破解变慢;加盐让攻击者无法用预先算好的彩虹表批量破解。数据库只存 salt+hash,不存明文。
"哈希碰撞绝不可能"对吗?
不对。输出空间有限,碰撞理论上必然存在,安全哈希的目标是让它"极难找到"。SHA-1 已不安全,抗碰撞场景不要再用。
✅ 都能答上来?
那就掌握了哈希函数。可以继续学 古典密码 或回到 CH4 技术体系 看数字签名。
📝强化题库(20 选择 + 20 填空 = 40 题)
覆盖本讲全部知识点。选择题点选即时判分;填空题输入后点"检查"或"显示答案"。
已答 0/20
答对 0
正确率 —
已检查 0/20
答对 0