# SHA-256 详解
## 名字含义拆解
**SHA-256 = SHA + 256**
```Java
git log
commit 185f8db32271fe25f561a6fc938b2e264306ec304e
Author: 张三 <
[email protected]>
Date: 2023-07-15 14:32:10 +0800
```
这就是提交内容的SHA-256哈希(实际是SHA-1)
# SHA 是什么?
**SHA = Secure Hash Algorithm**
- **Secure** = 安全的
- **Hash** = 哈希/散列
- **Algorithm** = 算法
翻译:**安全哈希算法**
---
# 256 是什么意思?
**256 = 输出的位数(bits)**
- 输出 **256 位**(bits)的二进制数
- 256 位 = 32 字节(bytes)
- 32 字节 = 64 个十六进制字符
## 转换关系
```Java
256 bits(位)
= 256 ÷ 8 = 32 bytes(字节)
= 32 × 2 = 64 个十六进制字符
例如:
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
↑________________________________________________↑
64个字符
```
---
# 哈希(Hash)是什么?
## 通俗定义:把任意长度的数据变成固定长度的"指纹"
**生活类比:榨汁机**
```Java
输入(水果) 榨汁机 输出(果汁)
─────────────────→ ┌─────┐ ────→ ─────────
🍎 苹果 │SHA- │ 🥤 250ml
🍎🍎🍎 三个苹果 │ 256 │ 🥤 250ml
🍉 西瓜 │ │ 🥤 250ml
🍇🍓🍊 混合水果 └─────┘ 🥤 250ml
特点:
- 无论放多少水果 → 输出都是250ml
- 不同水果 → 不同味道的果汁
- 无法从果汁还原出水果
```
---
# 为什么叫"安全"哈希?
**对比:普通哈希 vs 安全哈希**
## 普通哈希(不安全)
python
```python
# 简单的哈希函数
def simple_hash(text):
return len(text) # 只返回长度
simple_hash("Hello") → 5
simple_hash("World") → 5
simple_hash("abcde") → 5
```
❌ 问题:很多不同输入产生相同输出(**碰撞**)
## 安全哈希(SHA-256)
python
```python
sha256("Hello") → a591a6d40bf420404a011733cfb7b190...
sha256("World") → 78ae647d...(完全不同)
sha256("Hellp") → 9b871512...(改一个字母,哈希完全变)
```
✅ **"安全"的含义:**
1. **抗碰撞性**:几乎不可能找到两个不同输入产生相同哈希
2. **单向性**:无法从哈希值反推原文
3. **雪崩效应**:输入改一点点,输出完全改变
---
# SHA 家族
SHA不是一个算法,而是一个**家族**:
|算法|输出长度|发布年份|状态|
|---|---|---|---|
|**SHA-0**|160位|1993|❌ 已破解,不安全|
|**SHA-1**|160位|1995|⚠️ 已破解(2017),淘汰中|
|**SHA-256**|256位|2001|✅ 安全,广泛使用|
|**SHA-384**|384位|2001|✅ 安全|
|**SHA-512**|512位|2001|✅ 安全|
## 为什么现在用SHA-256?
```Java
SHA-1(160位):
- 2^160 ≈ 1.46 × 10^48 种可能
- 2017年Google破解(找到碰撞)
- 不再安全 ❌
SHA-256(256位):
- 2^256 ≈ 1.16 × 10^77 种可能
- 比宇宙中原子数量还多
- 目前安全 ✅
```