Pythonで理解するハッシュ化の基礎
ハッシュ化とは?
ハッシュ化とは、入力したデータ(文字列や数字)を一定のルール(ハッシュ関数)に基づいて変換し、「ハッシュ値」という固定長の値にすることです。
- 同じ入力には同じハッシュ値が出ます。
- 少しでも違う入力だと、まったく異なる値になります。
- 基本的には、元のデータを復元することはできません。
ハッシュ化のサンプルコード(簡易版)
サンプルコード
def simple_hash(text, hash_size=1024):
hash_value = 0
for char in text:
# 文字のASCIIコードを利用
hash_value = (hash_value * 31 + ord(char)) % hash_size
return hash_value
# 使用例
print(simple_hash("Hello"))
print(simple_hash("World"))
print(simple_hash("Hello World"))
コードの解説(初心者向け)
-
ord(char)
で文字を数値(ASCIIコード)に変換します。例:'A'
は65
です。 -
31
は素数で、データのばらつきを良くするために使用します。 -
% hash_size
は、最終的なハッシュ値を一定の範囲内に収めるための計算(割り算の余り)です。
ハッシュ化のサンプルコード(複雑版)
サンプルコード
def custom_hash(text, hash_size=65536):
hash_value = 0xABCDEF
for char in text:
hash_value ^= ord(char) # XOR演算
hash_value = (hash_value << 5) | (hash_value >> 27) # ビットローテーション
hash_value &= 0xFFFFFFFF # 32ビットに制限
return hash_value % hash_size
# 使用例
print(custom_hash("Hello"))
print(custom_hash("World"))
print(custom_hash("Hello World"))
コードの解説(初心者向け)
-
^
はXOR(エックスオア)演算で、「同じなら0、異なれば1」を返す計算です。入力データを変えると結果が大きく変化しやすくなります。 -
<<
,>>
はビットローテーションで、データを左右に回転させることで、値の多様性を高めています。 -
% hash_size
は値を一定の範囲に収めるために使用します。
素数(31)を使う理由
素数をハッシュ関数に使用すると、データの値が均等に散らばりやすくなります。31がよく使われる理由は、計算効率が良く、経験的にデータが適度に分散することが分かっているからです。
ハッシュ化と暗号化の違い
ハッシュ化と暗号化は混同されがちですが、実は異なる性質を持っています。
項目 | ハッシュ化 | 暗号化 |
---|---|---|
特徴 | 一方向(戻せない) | 双方向(戻せる) |
復元可能? | ❌ 基本的に不可能 | ⭕️ 鍵を使って復号可能 |
用途例 | パスワード保存、データ検証 | データの安全な通信、保存 |
暗号化のサンプルコード(Pythonの例)
from cryptography.fernet import Fernet
# 鍵を生成
key = Fernet.generate_key()
cipher = Fernet(key)
# 暗号化する
encrypted = cipher.encrypt(b"Hello World")
print(encrypted)
# 復号する(元に戻す)
decrypted = cipher.decrypt(encrypted)
print(decrypted.decode())
まとめ
- ハッシュ化は、データを復元不可能な固定長の値に変換します。
- シンプルな実装でもハッシュ関数の概念を理解できます。
- 実際の用途に応じて、ハッシュ化と暗号化を正しく使い分けることが大切です。