雜湊(Hash)是程式設計中將任意長度輸入資料透過特定演算法轉換為固定長度輸出值的機制,產生獨特的「指紋」摘要,用於快速檢索、資料完整性驗證與密碼安全。它具有單向性質,從雜湊值無法反推原始資料,廣泛應用於資料結構、加密與快取系統。
雜湊的核心特性與原理
優質雜湊函數必須具備以下特性:
-
固定長度輸出:無論輸入 1 字元或 1GB 檔案,輸出固定位元數(如 SHA-256 產生 256 位)
-
確定性:相同輸入永遠產生相同輸出
-
雪崩效應:輸入微小變更導致輸出劇烈變化
-
抗碰撞性:極難找到兩個不同輸入產生相同輸出
-
不可逆性:無法從雜湊值還原原始資料
簡單範例(Python):
import hashlib
text = "Hello World"
hash_value = hashlib.sha256(text.encode()).hexdigest()
print(hash_value) # 將產生固定 64 位十六進位字串
# a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
雜湊表(Hash Table)資料結構
最常見應用是雜湊表,將鍵(Key)透過雜湊函數映射至陣列索引,實現平均 O(1) 查詢效率:
姓名 → 雜湊函數 → 索引 → 資料
"Alice" → hash("Alice") = 3 → array[3] = {name: "Alice", age: 25}
"Bob" → hash("Bob") = 7 → array[7] = {name: "Bob", age: 30}
Python 實作:
# 內建 dict 即雜湊表
user_data = {
"alice": {"age": 25, "city": "Taipei"},
"bob": {"age": 30, "city": "Kaohsiung"}
}
print(user_data["alice"]) # O(1) 存取
常見雜湊演算法分類
| 演算法 | 輸出長度 | 用途 | 安全性 |
|---|---|---|---|
| MD5 | 128 位 | 檔案校驗(不安全) | 已破壞 |
| SHA-1 | 160 位 | 舊版簽章(不推薦) | 已破壞 |
| SHA-256 | 256 位 | 區塊鏈、數位簽章 | 安全 |
| SHA-3 | 變長 | 後量子密碼學 | 最安全 |
| CRC32 | 32 位 | 錯誤偵測 | 非加密 |
實際程式設計應用場景
1. 密碼儲存
import hashlib
import os
def hash_password(password: str) -> str:
salt = os.urandom(32) # 隨機鹽值防彩虹表
pwd_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
return salt.hex() + ':' + pwd_hash.hex()
2. 檔案完整性驗證
# 下載後驗證
sha256sum --check checksum.txt
echo "大檔案.sha256 大檔案 OK"
3. 快取系統
cache = {}
def get_expensive_result(key):
if key in cache:
return cache[key] # O(1) 快取命中
result = compute_heavy_calculation(key)
cache[key] = result # 雜湊表儲存
return result
雜湊碰撞與解決策略
碰撞問題:不同輸入產生相同雜湊值,概率雖低但不可避免。
解決方法:
-
鏈結法:每個索引存清單
array[3] = [obj1, obj2] -
開放定址法:線性探測
hash(key) + i -
再雜湊法:多個雜湊函數輪替
理想:key1→3, key2→7
碰撞:key1→3, key3→3 [鏈結: array[3] = [key1, key3]]
語言內建雜湊函數範例
# Python 自動雜湊(用於 dict、set)
print(hash("hello")) # 每次運行可能不同(防 DOS)
print(hash((1, 2, 3))) # 元組可雜湊
# JavaScript 物件鍵自動雜湊
obj = { "key": "value" } # 內部轉為雜湊表
# Go 內建 map
m := make(map[string]int)
m["age"] = 25
安全性應用與注意事項
安全雜湊實務:
-
永遠搭配鹽值(Salt):
hash(password + salt) -
使用慢速演算法:bcrypt、Argon2 防暴力破解
-
避免 MD5/SHA-1:已知碰撞攻擊
-
定期升級演算法:密碼學快速演進
常見陷阱:
不安全的密碼雜湊
hashlib.sha256("password123".encode()).hexdigest()
安全的密碼雜湊
bcrypt.hashpw("password123".encode(), bcrypt.gensalt())
雜湊是程式設計的萬用工具,從資料結構到區塊鏈無所不在。理解其原理與限制,能大幅提升程式效能、安全性與可維護性,是從初學者到專業開發者的必備知識。