各バイナリアセットに対して、MD5ハッシュを生成します。これは、特定のバイナリアセットがアプリケーションに既に存在するかどうかを確認するために使用されます。ただし、2つの異なるバイナリアセットが同じMD5ハッシュを生成する可能性はあります。 2つの異なる文字列が同じMD5ハッシュを生成する可能性はありますか?
数十億の資産のセットの場合、ランダムな衝突の可能性はごくわずかです-心配する必要はありません。 birthday paradox を考慮すると、2 ^ 64(または18,446,744,073,709,551,616)アセットのセットが与えられると、このセット内でa single MD5コリジョンの確率は50%です。この規模では、ストレージ容量の点でおそらくGoogleに勝るでしょう。
ただし、MD5ハッシュ関数が壊れているため( 衝突攻撃 に対して脆弱です)、任意の攻撃者は2つの衝突する資産を生成できますわずか数秒でCPUのパワーが上がります。したがって、MD5を使用する場合は、そのような攻撃者がアプリケーションのセキュリティを侵害しないようにしてください。
また、攻撃者がデータベース内の既存のアセットと衝突する可能性がある場合の影響も考慮してください。 MD5に対するそのような既知の攻撃( preimage attack )はありませんが(2011年現在)、衝突攻撃に関する現在の研究を拡張することで可能になる可能性があります。
これらが問題になる場合は、SHA-2シリーズのハッシュ関数(SHA-256、SHA-384、SHA-512)を調べることをお勧めします。マイナス面は、わずかに遅くなり、ハッシュ出力が長くなることです。
MD5は ハッシュ関数 –ですから、はい、2つの異なる文字列が衝突するMD5コードを絶対に生成できます。
特に、MD5コードは固定長であるため、MD5コードの可能な数が制限されていることに注意してください。ただし、(任意の長さの)文字列の数は間違いなく無制限なので、論理的にはmustが衝突することになります。
はい、もちろん:MD5ハッシュの長さには制限がありますが、MD5ハッシュできる文字列の数には限りがあります。
はい、2つの異なる文字列が同じMD5ハッシュコードを生成する可能性があります。
以下は、16進文字列で非常によく似たバイナリメッセージを使用した簡単なテストです。
$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c6b384c4968b28812b676b49d40c09f8af4ed4cc -
008ee33a9d58b51cfeb425b0959121c9
$ echo '4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
c728d8d93091e9c7b87b43d9e33829379231d7ca -
008ee33a9d58b51cfeb425b0959121c9
それらは異なるSHA-1合計を生成しますが、同じMD5ハッシュ値を生成します。第二に、文字列は非常に似ているため、それらの違いを見つけるのは困難です。
違いは次のコマンドで確認できます。
$ diff -u <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2 | fold -w2) <(echo 4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2 | fold -w2)
--- /dev/fd/63 2016-02-05 12:55:04.000000000 +0000
+++ /dev/fd/62 2016-02-05 12:55:04.000000000 +0000
@@ -33,7 +33,7 @@
af
bf
a2
-00
+02
a8
28
4b
@@ -53,7 +53,7 @@
6d
a0
d1
-55
+d5
5d
83
60
上記の衝突例は、マークスティーブンスからのものです。 MD5の単一ブロック衝突 、2012;彼は、ソースコード( 論文への代替リンク )を使用してメソッドを説明します。
別のテスト:
$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
756f3044edf52611a51a8fa7ec8f95e273f21f82 -
cee9a457e790cf20d4bdaa6d69f01e41
$ echo '0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef' | xxd -r -p | tee >/dev/null >(md5) >(sha1sum)
6d5294e385f50c12745a4d901285ddbffd3842cb -
cee9a457e790cf20d4bdaa6d69f01e41
異なるSHA-1合計、同じMD5ハッシュ。
違いは1バイトです。
$ diff -u <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2) <(echo 0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef | fold -w2)
--- /dev/fd/63 2016-02-05 12:56:43.000000000 +0000
+++ /dev/fd/62 2016-02-05 12:56:43.000000000 +0000
@@ -19,7 +19,7 @@
03
65
9e
-70
+74
4f
85
34
@@ -41,7 +41,7 @@
a3
f4
15
-5c
+dc
bb
86
07
上記の例は、Tao XieおよびDengguo Fengからの抜粋です: Construct MD5 Collisions Using Just A Single Block of Message 、2010。
関連:
もっと参考になるように。数学的な観点から見ると、ハッシュ関数はinjectiveではありません。
これは、開始セットと結果セットの間に1対1(ただし一方向)の関係がないことを意味します。
編集:完全な単射ハッシュ関数が存在する:それは 完全なハッシュ と呼ばれています。
はい、そうです!衝突が可能性があります(ただし、リスクは非常に小さいです)。そうでない場合は、かなり効果的な圧縮方法があります!
[〜#〜] edit [〜#〜]:Konrad Rudolphが言うように:有限の出力セットに変換される潜在的に無制限の入力セット(32の16進文字)willは、無限の衝突をもたらします。
他の人が言ったように、はい、2つの異なる入力間で衝突が発生する可能性があります。しかし、ユースケースでは、それが問題であることはわかりません。前の仕事で多数の画像(JPG、ビットマップ、PNG、生)形式の数十万の画像ファイルをフィンガープリントするためにMD5を使用しましたが、衝突はありませんでした。 。
ただし、ある種のデータをフィンガープリントしようとする場合、おそらく2つのハッシュアルゴリズムを使用できます。1つの入力が2つの異なるアルゴリズムの同じ出力をもたらす確率はほぼ不可能です。
私はこれが古いことを理解していますが、私は自分のソリューションに貢献すると思いました。 2 ^ 128の可能なハッシュの組み合わせがあります。したがって、誕生日の逆説の確率は2 ^ 64です。以下の解決策は衝突の可能性を排除しませんが、それは確かに非常にかなりの量だけリスクを減らすでしょう。
2^64 = 18,446,744,073,709,500,000 possible combinations
私がやったことは、入力文字列に基づいていくつかのハッシュをまとめて、ハッシュと見なす結果の文字列をはるかに長くすることです...
このための私の擬似コードは次のとおりです。
Result = Hash(string) & Hash(Reverse(string)) & Hash(Length(string))
それは衝突の実際的な起こりそうもないことです。しかし、あなたが超妄想的になりたくて、それを起こせないなら、ストレージスペースは問題ではありません(コンピューティングサイクルもそうではありません)...
Result = Hash(string) & Hash(Reverse(string)) & Hash(Length(string))
& Hash(Reverse(SpellOutLengthWithWords(Length(string))))
& Hash(Rotate13(string)) Hash(Hash(string)) & Hash(Reverse(Hash(string)))
さて、最もクリーンなソリューションではありませんが、これにより、衝突が発生する頻度が少なくなるので、より多くの遊びができます。その点まで、私はこの用語のすべての現実的な意味において不可能を想定しているかもしれません。
私の考えでは、衝突の可能性はあまりないので、これを「確実な火事」ではないと考えますが、発生する可能性は低いので、ニーズに合うと思います。
これで、可能な組み合わせが大幅に増えました。あなたはこれがあなたにどれだけの組み合わせをもたらすかについて長い時間を費やすことができますが、理論的には上記の引用された数よりもかなり多く着陸すると言います
2^64 (or 18,446,744,073,709,551,616)
おそらくさらに100桁程度です。これにより得られる理論上の最大値は
結果の文字列の可能な数:
528294531135665246352339784916516606518847326036121522127960709026673902556724859474417255887657187894674394993257128678882347559502685537250538978462939576908386683999005084168731517676426441053024232908211188404148028292751561738838396898767036476489538580897737998336
ハッシュの衝突は予想したほどまれではないため、要件に従ってハッシュアルゴリズムを慎重に選択する必要があると思います。私は最近、プロジェクトでハッシュ衝突の非常に単純なケースを見つけました。 Pythonハッシュ用のxxhashのラッパー。リンク: https://github.com/ewencp/pyhashxx
s1 = 'mdsAnalysisResult105588'
s2 = 'mdsAlertCompleteResult360224'
pyhashxx.hashxx(s1) # Out: 2535747266
pyhashxx.hashxx(s2) # Out: 2535747266
システムで非常にトリッキーなキャッシュの問題が発生し、最終的にハッシュの衝突であることがわかりました。