ハッシュ関数とは
- 公開日:2018/03/11
- 更新日:2018/10/19
- 投稿者:n bit
今回はハッシュ関数に関する解説です。ブロックチェーンの暗号化の基礎となる技術で仮想通貨やブロックチェーンの解説にはよく出てくる用語です。ハッシュ関数には暗号化に適した特徴がいくつかあります。ハッシュ関数の基本から特徴までを事例を交えてわかりやすく解説していきます。
この記事は約 分で読めます。(文字)
ハッシュ関数って何?
ブロックチェーンの説明にはハッシュ関数と言う言葉が必ず出てきます。このハッシュ関数とは何でしょうか。理解するにはまず2つに分けて考えたほうがわかりやすいです。1つ目は関数、2つ目はハッシュ値です。
関数
関数と言う言葉は数学によく出てきます。数学が嫌いな人は関数と言う言葉を聞いただけでも嫌な感じがするかもしれませんが関数と言う概念はそんなに難しいものではありません。
関数とは「何かしらの入力に対して、決まった規則に従った出力を行う機能をもったもの」です。
- 何かしらの入力
↓ - 関数
↓ - 決まった規則に従った出力
たったこれだけです。
例えば、
2 → 関数 → 4
5 → 関数 → 10
20 → 関数 → 40
このような機能を持った関数があるとします。この関数の機能は、「何かしらの入力」が入ってくると2倍するという規則従った出力をすることです。
- 何かしらの入力
↓ - 関数(「何かしらの入力」を2倍する)
↓ - 決まった規則に従った出力(「何かしらの入力」を2倍したもの)
Note
中学校で最初に習う関数 \(y=2x\)
ここは興味がなければ読み飛ばしていただいて大丈夫です。ちなみに先ほど上記で例に使った、「何かしらの入力」を2倍する機能を持った関数は数学で最初の方に習う関数:\(y=2x\)です。
中学校の数学ではよく何かしらの入力を「\(x\)」、決まった規則に従った出力を「\(y\)」に置き換えます。
- 何かしらの入力「\(x\)」
↓ - 関数
↓ - 決まった規則に従った出力「\(y\)」
ようは、\(x\)を放り込むと\(y\)を吐き出す機能を持った関数と言うことです。\(y\)は\(x\)を2倍したものですので\(y=2×x\)、つまり、\(y=2x\)となります。
「何かしらの入力」を2倍する機能を持った関数を式で表すと:\(y=2x\) となります。
ハッシュ値
もう一つハッシュ値というものを理解しておく必要があります。ハッシュ値とは、元になる何かしらの入力データから一定の計算手順により求められた、規則性のない固定の長さの値です。
ビットコインでは規則性のない64文字の長さの値を使用しています。
例えば当サイトのタイトル「dot blog」からハッシュ値を求めると下記の64文字になります。
dot blog
de5ac9fe9da2ce1cff21ce4c9a99f22ce7f9c5c9c78849fa599a4fc6b3d6dc52
試しに「dot blog」の後ろに0〜2の数字を足してハッシュ値を求めてみます。
dot blog0
f5ae7a49152e8ff79d02dfe3e14d18e701cd2888f7e91997f3a44be557df6109
dot blog1
78d2bbafa47c589193f525207643ee1df2009bd60841698383fbee8395812508
dot blog2
6e501130a32a4edf937b3f45b2053154256574bcda1304f7a90edd95205ee59d
全て64文字になっています。そして「dot blog」に連番で数字を足していった規則性のある入力値にもかかわらず求められたハッシュ値には全く規則性がないことがわかります。このように何かしらの入力データから一定の計算手順により求められた規則性の持たない固定の長さの値をハッシュ値と呼んでいます。
ハッシュ関数
感の良い方はもうおわかりですね。ハッシュ関数とは「何かしらの入力」が入ると、「ある決まった規則に従ってハッシュ値を出力」する関数のことです。
- 何かしらの入力
↓ - 関数
↓ - 決まった規則に従ったハッシュ値を出力
今回の場合であれば64文字のハッシュ値を返すと言うルールです。
- ハッシュ関数 = ハッシュ値を求める関数
- ハッシュ値 = ハッシュ関数により求められる値
64文字はビットと言う単位に変換すると256ビットで、256ビットの長さへ変換する計算手順(アルゴリズム)を定義したものなので【 Secure Hash Algorithm 256-bit 】 、略して SHA-256 と呼びます。
先ほどの例の様に「SHA-256」という関数(ハッシュ関数)は、「何かしらの入力」を行うと、それに基づいた256ビット(64文字)のハッシュ値を返します。
- dot blog
↓ - 関数:ハッシュ関数SHA-256
↓ - de5ac9fe9da2ce1cff21ce4c9a99f22ce7f9c5c9c78849fa599a4fc6b3d6dc52
ハッシュ値とハッシュ関数の特徴
ハッシュ値とハッシュ関数にはいくつかの暗号化に適した特徴があります。
特徴
- 同じ入力値に対しては必ず同じハッシュ値が出力される
- 入力値に対して規則性のないハッシュ値が出力される
- ハッシュ値から元の入力データに復元することはほぼ不可能
がハッシュ関数の特徴です。
Note
「規則性のないハッシュ値が出力される」とありますが正確にはあるルールに従って規則性がないように見えるハッシュ値を出力しています。が、話がややこしくなるので「規則性のないハッシュ値」が出力されると認識しておいて問題ありません。
同じ入力値に対しては必ず同じハッシュ値が出力される
言葉の通りですが同じ入力値であればいつハッシュ関数に通してハッシュ値を求めても必ず同じハッシュ値が出力されます。「dot blog」をハッシュ関数に通すといつでも下記のような変換になります。
- dot blog
↓ - 関数:ハッシュ関数SHA-256
↓ - de5ac9fe9da2ce1cff21ce4c9a99f22ce7f9c5c9c78849fa599a4fc6b3d6dc52
入力値に対して規則性のないハッシュ値が出力される
「dot blog」の後ろに0〜2の数字を足してハッシュ値に変換したことを思い出してください。dot blog0
f5ae7a49152e8ff79d02dfe3e14d18e701cd2888f7e91997f3a44be557df6109
dot blog1
78d2bbafa47c589193f525207643ee1df2009bd60841698383fbee8395812508
dot blog2
6e501130a32a4edf937b3f45b2053154256574bcda1304f7a90edd95205ee59d
このように連番の入力値を使ったにもかかわらず出力されたハッシュ時には全く規則性がありません。ほんの少しでも入力値が変わると出力されるハッシュ値はガラリと変わるのです。ここにはもう一つ重要なポイントがあり、違う入力データから同じハッシュ値が出力される事はほぼありません。
例えば、入力値「dot blog0」から出力された出力値、
f5ae7a49152e8ff79d02dfe3e14d18e701cd2888f7e91997f3a44be557df6109
は、「dot blog0」以外の入力値から生成される事はありません。
ハッシュ値から元の入力データに復元することはほぼ不可能
ハッシュ値は、「入力値→ハッシュ値」の計算はとても早く簡単だけど「入力値←ハッシュ値」に復元することはほぼ不可能と言うことです。この、ハッシュ値から元の入力データを復元できないこともブロックチェーンの暗号化における重要なポイントです。
ハッシュ値は不可逆なデータで、その性質が暗号化と非常に相性が良いことから暗号や認証、ハッシュ値を使ったデータ改ざんのチェック等に応用されいます。
試しにハッシュ値を生成してみる
ハッシュ値の変換がどのようなものか体験してみたい方は下記のサイトにアクセスして上側の入力ウインドウに適当な文字列を入力し生成ボタンを押してみてください。
pythonであれば下記コードでも生成できます。(Python3系)
# -*- coding: utf-8 -*-
import sys
import hashlib
def hash_out(string):
hash_value = hashlib.sha256(string.encode('utf-8')).hexdigest()
return hash_value
if __name__ == '__main__':
# string = sys.argv[1]
string = 'dotblog2'
hash_value = hash_out(string)
print(hash_value)
ターミナルで以下のように入力してください。
$ python hash.py 入力文字列
今日のdot
ハッシュ関数とは「何かしらの入力」が入ると、「ある決まった規則に従ってハッシュ値を出力」する関数でビットコインのブロックチェーンではSHA-256と言うハッシュ関数が利用されています。
ハッシュ関数には暗号化に適した次のような特徴があります。
- 同じ入力値に対しては必ず同じハッシュ値が出力される
- 入力値に対して規則性のないハッシュ値が出力される
- ハッシュ値から元の入力データに復元することはほぼ不可能