ハッシュ関数に関するウィキペディアの記事は非常に優れていますが、ここで私の見解を示します。
ハッシュとは何ですか?
「ハッシュ」は、実際にはさまざまな文脈でさまざまな正式な意味を持つ広義の用語です。あなたの質問に対する完璧な答えはありません。一般的な基礎概念を説明し、この用語の最も一般的な用法のいくつかに言及します。
「ハッシュ」とは、
入力オブジェクトとして文字列または数値を出力するハッシュ関数と呼ばれる関数です。入力オブジェクトは、通常、文字列、整数、またはユーザー定義構造のような他のオブジェクトで構成される大きなデータ型のような基本データ型のメンバーです。出力は通常、数値または文字列です。名詞「ハッシュ」はしばしばこの出力を指します。「ハッシュ」という動詞は、しばしば「ハッシュ関数を適用する」という意味です。ハッシュ関数に必要な主なプロパティは次のとおりです。h
- 計算が簡単で、
- 出力は比較的小さくする必要があります。
例:
0から999,999,999の範囲の数字を0から99の数字にハッシュしたいとします。1つの単純なハッシュ関数はです。h(x)=xmod100
一般的な追加プロパティ:
ユースケースによっては、ハッシュ関数が追加のプロパティを満たすようにしたい場合があります。一般的な追加プロパティを次に示します。
均一性:オブジェクトのハッシュを明確にしたいことがよくあります。さらに、ハッシュを「広げる」こともできます。一部のオブジェクトを100個のバケットにハッシュする場合(ハッシュ関数の出力は0から99までの数値です)、通常、バケット1に約1/100個のオブジェクトが、バケット1に約1/100個の土地がバケット1など。
暗号の耐衝突性:時にはこれはさらに先に進みます。たとえば、暗号では、同じ出力にマップされる2つの異なる入力を敵が見つけるのが計算上困難なハッシュ関数が必要な場合があります。
圧縮:しばしば、任意の大きさの入力を一定サイズの出力または固定数のバケットにハッシュしたい。
決定論:実行ごとに出力が変化しないハッシュ関数が必要な場合があります。つまり、同じオブジェクトでのハッシュ関数の出力は常に同じままです。これは上記の均一性と矛盾するように思えるかもしれませんが、1つの解決策はハッシュ関数をランダムに1回選択し、実行ごとに変更しないことです。
いくつかのアプリケーション
一般的なアプリケーションの1つは、辞書を実装する方法であるハッシュテーブルなどのデータ構造です。ここでは、100個の「バケット」などのメモリを割り当てます。次に、(キー、値)ペアを辞書に保存するように求められたら、キーを0〜99の数字にハッシュし、メモリ内の対応するバケットにペアを保存します。次に、キーを検索するように求められたら、同じハッシュ関数を使用してキーを0〜99の数字にハッシュし、そのキーがそこにあるかどうかを確認します。その場合、その値を返します。
バイナリ検索ツリーなど、他の方法で辞書を実装することもできることに注意してください(オブジェクトが同等である場合)。
別の実用的なアプリケーションはチェックサムです。これは、2つのファイルが同じであることを確認する方法です(たとえば、ファイルは以前のバージョンから破損していません)。ハッシュ関数が2つの入力を同じ出力にマップすることはほとんどないため、通常は文字列として表される最初のファイルのハッシュを計算して保存します。このハッシュは非常に小さく、おそらく数十個のASCII文字だけです。次に、2番目のファイルを取得したら、それをハッシュし、出力が同じであることを確認します。もしそうなら、ほぼ確実にバイト単位でまったく同じファイルです。
別のアプリケーションは暗号化にあります。これらのハッシュは「反転」するのが難しいはずです。つまり、出力とハッシュ関数が与えられると、その出力につながった入力を計算するのは計算上困難です。これの1つの使用法はパスワードです。パスワード自体を保存する代わりに、パスワードの暗号化ハッシュを保存します(他のいくつかの要素を使用して)。次に、ユーザーがパスワードを入力すると、そのハッシュを計算し、正しいハッシュと一致することを確認します。その場合、パスワードが正しいと言います。(サーバーに保存されたハッシュを調べて見つけることができる人でさえ、ユーザーのふりをするのはそれほど簡単ではありません。)このアプリケーションは、出力が入力と同じかそれより長い場合です。入力が非常に短い。