非暗号化用途の最速のハッシュ?


154

私は基本的にデータベースに入れるフレーズを準備していますが、形式が正しくない可能性があるため、代わりに短いハッシュを保存します(存在するかどうかを単純に比較するので、ハッシュが理想的です)。

MD5は100,000以上のリクエストでかなり遅いと思うので、フレーズをハッシュするための最良の方法は何かを知りたかったのですが、おそらく自分のハッシュ関数をロールアウトするhash('md4', '...'か、結局はより高速になりますか?

MySQLにはMD5()があることを知っているので、クエリの終了時に少し高速になりますが、MySQLにはさらに高速なハッシュ関数があり、PHPで動作することを知りません。


6
ハッシュのベンチマークを妨げているのは何ですか?
NullUserException

3
NullUserException:そのとおりです。ランダムな長さのフレーズで試してみます。この種のことを処理するための規範があるとすれば、それに対する洞察が欲しかっただけです。
John

5
MD5は...本当に遅いではありません
アンバー

25
ハッシュ関数がアプリケーション全体のボトルネックであると確信していますか?私はそうは思いません
あなたの常識

4
これは非常に良い質問であり、そうではない、または重要ではない、および/または明白かつ/または直感的である必要があることを暗示するコメントは、期待外れで苛立たしいものです。(また、まったく予想外です。)
マイケル

回答:


56

CRC32はかなり高速で、そのための関数があります。http//www.php.net/manual/en/function.crc32.php

ただし、CRC32はMD5またはSHA-1ハッシュよりも衝突が多いことに注意してください。これは、単純に長さが短くなっているためです(32ビットと128ビットの比較160ビット)。ただし、格納された文字列が破損しているかどうかを確認するだけの場合は、CRC32で問題ありません。


1
うわー、必要なデータ型のみが符号なし整数であり、これは他のハッシュよりもかなり高速です。
John

2
@ジョン:かどうか。CRC プロセッサは、ARMプロセッサではMD4 より遅く、MD5よりも速くないことがわかりました。さらに、CRC32は符号なし32ビット整数型を使用します。これは、MD5が必要とするものすべてです...
Thomas Pornin

3
新しいIntel cpuの利点/贅沢がある場合は、おそらく従来のcrc32値ではありませんが、おそらく非常に高速なcrc32cアセンブリコマンドがあります。xxhash code.google.com/p/xxhash
rogerdpack

146
fcn     time  generated hash
crc32:  0.03163  798740135
md5:    0.0731   0dbab6d0c841278d33be207f14eeab8b
sha1:   0.07331  417a9e5c9ac7c52e32727cfd25da99eca9339a80
xor:    0.65218  119
xor2:   0.29301  134217728
add:    0.57841  1105

そして、これを生成するために使用されるコードは次のとおりです。

 $loops = 100000;
 $str = "ana are mere";

 echo "<pre>";

 $tss = microtime(true);
 for($i=0; $i<$loops; $i++){
  $x = crc32($str);
 }
 $tse = microtime(true);
 echo "\ncrc32: \t" . round($tse-$tss, 5) . " \t" . $x;

 $tss = microtime(true);
 for($i=0; $i<$loops; $i++){
  $x = md5($str);
 }
 $tse = microtime(true);
 echo "\nmd5: \t".round($tse-$tss, 5) . " \t" . $x;

 $tss = microtime(true);
 for($i=0; $i<$loops; $i++){
  $x = sha1($str);
 }
 $tse = microtime(true);
 echo "\nsha1: \t".round($tse-$tss, 5) . " \t" . $x;

 $tss = microtime(true);
 for($i=0; $i<$loops; $i++){
  $l = strlen($str);
  $x = 0x77;
  for($j=0;$j<$l;$j++){
   $x = $x xor ord($str[$j]);
  }
 }
 $tse = microtime(true);
 echo "\nxor: \t".round($tse-$tss, 5) . " \t" . $x;

 $tss = microtime(true);
 for($i=0; $i<$loops; $i++){
  $l = strlen($str);
  $x = 0x08;
  for($j=0;$j<$l;$j++){
   $x = ($x<<2) xor $str[$j];
  }
 }
 $tse = microtime(true);
 echo "\nxor2: \t".round($tse-$tss, 5) . " \t" . $x;

 $tss = microtime(true);
 for($i=0; $i<$loops; $i++){
  $l = strlen($str);
  $x = 0;
  for($j=0;$j<$l;$j++){
   $x = $x + ord($str[$j]);
  }
 }
 $tse = microtime(true);
 echo "\nadd: \t".round($tse-$tss, 5) . " \t" . $x;

3
ああ、実際にこの洞察をありがとう、CRC32の私の使用が最速であることを強化するだけです。
John

@John-次を使用してハッシュアルゴリズムを取得できますhash_algos()。次のハッシュベンチマークコードは、PHPのコメントに含まれています==> codepad.viper-7.com/5Wdhw6
Peter Ajtai

コードをありがとうございます。少し改善しました。文字列全体を処理するmd5()のような関数と、xorで作成したようにバイトごとにループするループを比較する必要があるとは思いません。PHPでは、これらのループは非常に遅く、md5自体よりもさらに低速です。あるhasesを別のhasesと比較し、すべて関数として実装する必要があります。
Maxim Masiutin 2017

1
ちょっとしたメモ-私はこれをはるかに長い文字列(約5000文字)で試してみましたが、CRC32は私のマシン(i7-6650U、16GB)のMD5およびSHA1よりも低速でした。CRC32-1.7秒、​​MD5-1.4秒、SHA1-1.5秒。常に自分でテストしてください。
Sam Tolton 2017年

4
@Quamisテストは良いですが、誤解を招く可能性があります。@ samToltonが指摘したように、結果は異なり、md5高速です。より良いテストは、文字列の内容と長さもランダム化することです。このようにして、実際の実際のパフォーマンスについてより良いアイデアを得ます。これにより、キャッシュも回避されます。見てください: phpハッシュチェックサムパフォーマンス
Shlomi Hassid

43

各ループが他のすべてと同じ暗号化を共有するランクリスト。

<?php

set_time_limit(720);

$begin = startTime();
$scores = array();


foreach(hash_algos() as $algo) {
    $scores[$algo] = 0;
}

for($i=0;$i<10000;$i++) {
    $number = rand()*100000000000000;
    $string = randomString(500);

    foreach(hash_algos() as $algo) {
        $start = startTime();

        hash($algo, $number); //Number
        hash($algo, $string); //String

        $end = endTime($start);

        $scores[$algo] += $end;
    }   
}


asort($scores);

$i=1;
foreach($scores as $alg => $time) {
    print $i.' - '.$alg.' '.$time.'<br />';
    $i++;
}

echo "Entire page took ".endTime($begin).' seconds<br />';

echo "<br /><br /><h2>Hashes Compared</h2>";

foreach($scores as $alg => $time) {
    print $i.' - '.$alg.' '.hash($alg,$string).'<br />';
    $i++;
}

function startTime() {
   $mtime = microtime(); 
   $mtime = explode(" ",$mtime); 
   $mtime = $mtime[1] + $mtime[0]; 
   return $mtime;   
}

function endTime($starttime) {
   $mtime = microtime(); 
   $mtime = explode(" ",$mtime); 
   $mtime = $mtime[1] + $mtime[0]; 
   $endtime = $mtime; 
   return $totaltime = ($endtime - $starttime); 
}

function randomString($length) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
    $string = '';    
    for ($p = 0; $p < $length; $p++) {
        $string .= $characters[mt_rand(0, strlen($characters) - 1)];
    }
    return $string;
}

?>

そして出力

1 - crc32b 0.111036300659
2 - crc32 0.112048864365
3 - md4 0.120795726776
4 - md5 0.138875722885
5 - sha1 0.146368741989
6 - adler32 0.15501332283
7 - tiger192,3 0.177447080612
8 - tiger160,3 0.179498195648
9 - tiger128,3 0.184012889862
10 - ripemd128 0.184052705765
11 - ripemd256 0.185411214828
12 - salsa20 0.198500156403
13 - salsa10 0.204956293106
14 - haval160,3 0.206098556519
15 - haval256,3 0.206891775131
16 - haval224,3 0.206954240799
17 - ripemd160 0.207638263702
18 - tiger192,4 0.208125829697
19 - tiger160,4 0.208438634872
20 - tiger128,4 0.209359407425
21 - haval128,3 0.210256814957
22 - sha256 0.212738037109
23 - ripemd320 0.215386390686
24 - haval192,3 0.215610980988
25 - sha224 0.218329429626
26 - haval192,4 0.256464719772
27 - haval160,4 0.256565093994
28 - haval128,4 0.257113456726
29 - haval224,4 0.258928537369
30 - haval256,4 0.259262084961
31 - haval192,5 0.288433790207
32 - haval160,5 0.290239810944
33 - haval256,5 0.291721343994
34 - haval224,5 0.294484138489
35 - haval128,5 0.300224781036
36 - sha384 0.352449893951
37 - sha512 0.354603528976
38 - gost 0.392376661301
39 - whirlpool 0.629067659378
40 - snefru256 0.829529047012
41 - snefru 0.833986997604
42 - md2 1.80192279816
Entire page took 22.755341053 seconds


Hashes Compared

1 - crc32b 761331d7
2 - crc32 7e8c6d34
3 - md4 1bc8785de173e77ef28a24bd525beb68
4 - md5 9f9cfa3b5b339773b8d6dd77bbe931dd
5 - sha1 ca2bd798e47eab85655f0ce03fa46b2e6e20a31f
6 - adler32 f5f2aefc
7 - tiger192,3 d11b7615af06779259b29446948389c31d896dee25edfc50
8 - tiger160,3 d11b7615af06779259b29446948389c31d896dee
9 - tiger128,3 d11b7615af06779259b29446948389c3
10 - ripemd128 5f221a4574a072bc71518d150ae907c8
11 - ripemd256 bc89cd79f4e70b73fbb4faaf47a3caf263baa07e72dd435a0f62afe840f5c71c
12 - salsa20 91d9b963e172988a8fc2c5ff1a8d67073b2c5a09573cb03e901615dc1ea5162640f607e0d7134c981eedb761934cd8200fe90642a4608eacb82143e6e7b822c4
13 - salsa10 320b8cb8498d590ca2ec552008f1e55486116257a1e933d10d35c85a967f4a89c52158f755f775cd0b147ec64cde8934bae1e13bea81b8a4a55ac2c08efff4ce
14 - haval160,3 27ad6dd290161b883e614015b574b109233c7c0e
15 - haval256,3 03706dd2be7b1888bf9f3b151145b009859a720e3fe921a575e11be801c54c9a
16 - haval224,3 16706dd2c77b1888c29f3b151745b009879a720e4fe921a576e11be8
17 - ripemd160 f419c7c997a10aaf2d83a5fa03c58350d9f9d2e4
18 - tiger192,4 112f486d3a9000f822c050a204d284d52473f267b1247dbd
19 - tiger160,4 112f486d3a9000f822c050a204d284d52473f267
20 - tiger128,4 112f486d3a9000f822c050a204d284d5
21 - haval128,3 9d9155d430218e4dcdde1c62962ecca3
22 - sha256 6027f87b4dd4c732758aa52049257f9e9db7244f78c132d36d47f9033b5c3b09
23 - ripemd320 9ac00db553b51662826267daced37abfccca6433844f67d8f8cfd243cf78bbbf86839daf0961b61d
24 - haval192,3 7d706dd2d37c1888eaa53b154948b009e09c720effed21a5
25 - sha224 b6395266d8c7e40edde77969359e6a5d725f322e2ea4bd73d3d25768
26 - haval192,4 d87cd76e4c8006d401d7068dce5dec3d02dfa037d196ea14
27 - haval160,4 f2ddd76e156d0cd40eec0b8d09c8f23d0f47a437
28 - haval128,4 f066e6312b91e7ef69f26b2adbeba875
29 - haval224,4 1b7cd76ea97c06d439d6068d7d56ec3d73dba0373895ea14e465bc0e
30 - haval256,4 157cd76e8b7c06d432d6068d7556ec3d66dba0371c95ea14e165bc0ec31b9d37
31 - haval192,5 05f9ea219ae1b98ba33bac6b37ccfe2f248511046c80c2f0
32 - haval160,5 e054ec218637bc8b4bf1b26b2fb40230e0161904
33 - haval256,5 48f6ea210ee1b98be835ac6b7dc4fe2f39841104a37cc2f06ceb2bf58ab4fe78
34 - haval224,5 57f6ea2111e1b98bf735ac6b92c4fe2f43841104ab7cc2f076eb2bf5
35 - haval128,5 ccb8e0ac1fd12640ecd8976ab6402aa8
36 - sha384 bcf0eeaa1479bf6bef7ece0f5d7111c3aeee177aa7990926c633891464534cd8a6c69d905c36e882b3350ef40816ed02
37 - sha512 8def9a1e6e31423ef73c94251d7553f6fe3ed262c44e852bdb43e3e2a2b76254b4da5ef25aefb32aae260bb386cd133045adfa2024b067c2990b60d6f014e039
38 - gost ef6cb990b754b1d6a428f6bb5c113ee22cc9533558d203161441933d86e3b6f8
39 - whirlpool 54eb1d0667b6fdf97c01e005ac1febfacf8704da55c70f10f812b34cd9d45528b60d20f08765ced0ab3086d2bde312259aebf15d105318ae76995c4cf9a1e981
40 - snefru256 20849cbeda5ddec5043c09d36b2de4ba0ea9296b6c9efaa7c7257f30f351aea4
41 - snefru 20849cbeda5ddec5043c09d36b2de4ba0ea9296b6c9efaa7c7257f30f351aea4
42 - md2 d4864c8c95786480d1cf821f690753dc

4
最後に、最小の1つずれたエラーが発生します。:)strlen($characters)strlen($characters) - 1
MMである

29

xxhashサイトに速度の比較があります。ここにコピーして貼り付けます。

 Name            Speed       Q.Score   Author
 xxHash          5.4 GB/s     10
 MumurHash 3a    2.7 GB/s     10       Austin Appleby
 SpookyHash      2.0 GB/s     10       Bob Jenkins
 SBox            1.4 GB/s      9       Bret Mulvey
 Lookup3         1.2 GB/s      9       Bob Jenkins
 CityHash64      1.05 GB/s    10       Pike & Alakuijala
 FNV             0.55 GB/s     5       Fowler, Noll, Vo
 CRC32           0.43 GB/s     9
 MD5-32          0.33 GB/s    10       Ronald L. Rivest
 SHA1-32         0.28 GB/s    10

そのため、xxHashは断然最速であるようですが、CRC32、MD5、SHAなど、他の多くのハッシュは古いハッシュに勝っています。

https://code.google.com/p/xxhash/

これは32ビットコンパイルの順序であることに注意してください。64ビットのコンパイルでは、パフォーマンスの順序が大きく異なる可能性があります。一部のハッシュは、64ビットの乗算とフェッチに大きく基づいています。


17
+-------------------+---------+------+--------------+
|       NAME        |  LOOPS  | TIME |     OP/S     |
+-------------------+---------+------+--------------+
| sha1ShortString   | 1638400 | 2.85 | 574,877.19   |
| md5ShortString    | 2777680 | 4.11 | 675,834.55   |
| crc32ShortString  | 3847980 | 3.61 | 1,065,922.44 |
| sha1MediumString  | 602620  | 4.75 | 126,867.37   |
| md5MediumString   | 884860  | 4.69 | 188,669.51   |
| crc32MediumString | 819200  | 4.85 | 168,907.22   |
| sha1LongString    | 181800  | 4.95 | 36,727.27    |
| md5LongString     | 281680  | 4.93 | 57,135.90    |
| crc32LongString   | 226220  | 4.95 | 45,701.01    |
+-------------------+---------+------+--------------+

小さなメッセージ(この場合は26文字)の場合はcrc32の方が速く、長いメッセージ(この場合は> 852文字)の場合はmd5のようです。


17

2019年の更新:この回答は最新です。つぶやきをサポートするためのライブラリは、主にすべての言語で利用できます。

現在の推奨事項は、Murmur Hash Familyを使用することです(具体的には、murmur2またはmurmur3バリアントを参照してください)。

Murmurハッシュは、最小限の衝突(CRC、MDx、SHAxよりもはるかに高速)で高速ハッシュするように設計されています。重複を探すのに最適であり、HashTableインデックスに非常に適しています。

実際、さまざまな目的であらゆる種類のハッシュを計算するために、最近のデータベース(Redis、ElastisSearch、Cassandra)の多くで使用されています。この特定のアルゴリズムは、この10年間で多くのパフォーマンス向上の根本的な原因でした。

Bloom Filtersの実装でも使用されます。「高速ハッシュ」を検索している場合、おそらくブルームフィルターによって解決される典型的な問題に直面していることに注意してください。;-)

:murmurは汎用ハッシュであり、非暗号化を意味します。ハッシュを生成したソース「テキスト」を見つけることを妨げません。パスワードをハッシュすることは適切ではありません。

さらに詳細:MurmurHash-それは何ですか?


2
ここにmurmurhashをphpに追加するというオープンリクエストがあり、投票できます。
keune

8

MD5が「かなり遅い」と想定する代わりに、試してみてください。シンプルなPC上のMD5のシンプルなCベースの実装(私は、2.4 GHz Core2、シングルコアを使用)は、毎秒 600 の小さなメッセージをハッシュできます。小さなメッセージは、ここでは最大55バイトです。より長いメッセージの場合、MD5ハッシュ速度はメッセージサイズに比例します。つまり、データを毎秒約400メガバイトで処理します。これは、良好なハードディスクまたはギガビットイーサネットネットワークカードの最大速度の4倍であることに注意してください。

私のPCには4つのコアがあるので、これは、私のハードディスクが使用可能な計算能力の最大6%の使用を提供または受信できる最速のハッシュデータを意味します。ハッシュ速度がボトルネックになるか、PCに顕著なコストをもたらすには、非常に特殊な状況が必要です。

ハッシュ速度ある程度重要になる可能性があるはるかに小さいアーキテクチャでは、MD4を使用することができます。MD4は、非暗号化の目的には適しています(暗号化の目的では、MD5を使用しないでください)。ARMベースのプラットフォームでは、MD4はCRC32よりもさらに高速であると報告されています。


考慮すべき点があります。MD5は32ビットではなく128ビットを使用します。これは、データベースストレージのスペースが4倍多くなるため、ハッシュを比較するための検索が4倍遅くなることを意味します(と思います)。私が(私の用途で)気にしているのは、データベースがハッシュでいっぱいになったときに、後でデータベースをクエリする速度です。
Camilo Martin

3
十分に広い出力を使用しない場合、ランダムな衝突が発生します。目的は、特定の「フレーズ」がすでに知られているかどうかを確認するためにデータベースをクエリすることであるため、悪いことになります。ここでの衝突は誤検知に変わります。32ビットの場合、60000程度のフレーズを入力するとすぐに衝突が発生し始めます。これは、暗号化の有無にかかわらず、すべてのハッシュ関数に当てはまります。とはいえ、ハッシュ関数の出力をいつでも取得し、上記で説明した制限内で、適切な長さに切り詰めることができます。
Thomas Pornin

@ThomasPornin切り捨てると、再び衝突の問題が発生するのではないでしょうか。つまり、md5が衝突しにくいとされている唯一の理由は、CRC32と比較したときの余分な文字数です。
Mohd Abdul Mujib 2014年

4

警告

以下の答えは、ハッシュ関数を推奨していないため、尋ねられた質問に答えません。「ハッシュ関数は、任意のサイズのデータ​​を固定サイズの値にマッピングするために使用できる任意の関数です。」(ウィキペディア)以下の答えは、固定サイズの結果を保証しない変換を推奨しています。

ハッシュ関数を使用するという要件を緩和してもよい場合は、以下をお読みください...

元の回答

以下の理由により、urlencode()またはbase64_encode()をお勧めします。

  • 暗号化は必要ありません
  • あなたはスピードが欲しい
  • 「不正な」文字列をクリーンアップしながら、一意の文字列を識別する方法が必要です

これらの返信の他の場所でベンチマークコードを適応させて、これらのどちらもどのハッシュアルゴリズムよりもはるかに高速であることを示しました。アプリケーションによっては、urlencode()またはbase64_encode()を使用して、格納する「不正な」文字列をクリーンアップできる場合があります。


再:「 '不正な'文字列をクリーンアップするときに一意の文字列を識別する方法が必要です」:詳細について教えてください。
David J.

6年以上前に私が何を考えていたかを思い出すことは困難です... urlencodeまたはbase64_encodeとの衝突が発生しないため、結果は元の文字列と同じくらいユニークになるという事実を暗示していたかもしれません。
アナクロニスト

2

ステップ1:libsodiumをインストールする(またはPHP 7.2以降を使用していることを確認する)

ステップ2:次のいずれかを使用します。

  1. sodium_crypto_generichash()、これはBLAKE2bであり、ハッシュ関数はMD5よりも安全ですが、SHA256より高速です。(リンクにはベンチマークなどがあります)
  2. sodium_crypto_shorthash()これはSipHash-2-4です。これはハッシュテーブルに適していますが、衝突への耐性に依存すべきではありません。

_shorthashはの約3倍の速さ_generichashですが、キーが必要であり、衝突のリスクはわずかですが現実的です。では_generichash、衝突を心配する必要はなく、キーを使用する必要もありません(とにかく必要な場合があります)。


1
質問は「これはどれくらい速いですか」ですか?
My1 2016年

1
sodium_crypto_generichash(), which is BLAKE2b, a hash function more secure than MD5 but faster than SHA256. (Link has benchmarks, etc.)- blake2bは確かですが、blake2bのユーザランドPHPの実装では、PHPのためのC-実装SHA256よりも遅いがたくさんあることを行っている...私はPHPがhash_algosにblake2b adobtことがしたい()スイート...
hanshenrik

ここでは、純粋なPHPの実装は提案されていません。
Scott Arciszewski

1

高速でユニークなものを探している場合は、xxHashまたは新しいCPUのcrc32c組み込みコマンドを使用するものをお勧めします。https: //stackoverflow.com/a/11422479/32453を参照して ください。また、衝突の可能性をそれほど気にしない場合は、さらに高速なハッシュにリンクされます。


1

Adler32は私のマシンで最高のパフォーマンスを発揮します。そして、md5()より速く判明したcrc32()


3
MD5が一般的なCRC32関数より速い場合は、何かが非常に間違っています。
nxasdf 2015年

0

ハッシュ内のmd5の実装は、md5()よりも少し高速です。したがって、これはオプションか他のものになる可能性があります。試してください:

echo '<pre>';

$run = array();

function test($algo)
{
  #static $c = 0;
  #if($c>10) return;
  #$c++;

 $tss = microtime(true);
 for($i=0; $i<100000; $i++){
  $x = hash($algo, "ana are mere");
 }
 $tse = microtime(true);

 $GLOBALS['run'][(string)round($tse-$tss, 5)] = "\nhash({$algo}): \t".round($tse-$tss, 5) . " \t" . $x;
 #echo "\n$i nhash({$algo}): \t".round($tse-$tss, 5) . " \t" . $x;
}
array_map('test', hash_algos());
ksort($run);
print_r($run);
echo '</pre>';

あなたはhttp://www.dozent.net/Tipps-Tricks/PHP/hash-performanceで見ることができます


0

CRC32は高速ですが、MD5やSHA1よりも安全性が低くなります。MD5とSHA1の間にはそれほど速度の違いはありません。


MD5は安全でないと見なされています。SHA1よりもはるかに安全ではありません。MD5 wikiページを読んでください。
アーメド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.