[解決済み] 多次元配列の MD5 を行う PHP の最良の方法とは?
質問
多次元配列の MD5 (または他のハッシュ) を生成する最良の方法は何ですか?
私は、配列の各レベルをトラバースし、各値を文字列に連結し、その文字列に対して単純に MD5 を実行するループを簡単に書くことができました。
しかし、これは最高に面倒に思えるので、多次元配列を受け取り、それをハッシュ化するファンキーな関数があるかどうか疑問に思いました。
どのように解決するのか?
(下部にコピー&ペースト可能な機能あり)
前述したように、以下のようにするとうまくいきます。
md5(serialize($array));
しかし、(皮肉にも)json_encodeが実行するのは 顕著に より高速です。
md5(json_encode($array));
実際、(1) json_encode単独ではserializeよりも高速に動作し、(2) json_encodeではより小さな文字列を生成するため、md5が処理する量が少なくなるため、ここでは2倍の速度向上が期待できます。
編集してください。 この主張を裏付ける証拠がここにあります。
<?php //this is the array I'm using -- it's multidimensional.
$array = unserialize('a:6:{i:0;a:0:{}i:1;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:0:{}}}i:2;s:5:"hello";i:3;a:2:{i:0;a:0:{}i:1;a:0:{}}i:4;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:0:{}}}}}}}i:5;a:5:{i:0;a:0:{}i:1;a:4:{i:0;a:0:{}i:1;a:0:{}i:2;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:0:{}}i:3;a:6:{i:0;a:0:{}i:1;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:0:{}}}i:2;s:5:"hello";i:3;a:2:{i:0;a:0:{}i:1;a:0:{}}i:4;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:0:{}}}}}}}i:5;a:5:{i:0;a:0:{}i:1;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:0:{}}}i:2;s:5:"hello";i:3;a:2:{i:0;a:0:{}i:1;a:0:{}}i:4;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:0:{}}}}}}}}}}i:2;s:5:"hello";i:3;a:2:{i:0;a:0:{}i:1;a:0:{}}i:4;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:0:{}}}}}}}}}');
//The serialize test
$b4_s = microtime(1);
for ($i=0;$i<10000;$i++) {
$serial = md5(serialize($array));
}
echo 'serialize() w/ md5() took: '.($sTime = microtime(1)-$b4_s).' sec<br/>';
//The json test
$b4_j = microtime(1);
for ($i=0;$i<10000;$i++) {
$serial = md5(json_encode($array));
}
echo 'json_encode() w/ md5() took: '.($jTime = microtime(1)-$b4_j).' sec<br/><br/>';
echo 'json_encode is <strong>'.( round(($sTime/$jTime)*100,1) ).'%</strong> faster with a difference of <strong>'.($sTime-$jTime).' seconds</strong>';
JSON_ENCODEは一貫して250%(2.5倍)以上(しばしば300%以上)高速です -- これは些細な違いではありません。このライブスクリプトによるテスト結果はこちらでご覧になれます。
- http://nathanbrauer.com/playground/serialize-vs-json.php
- http://nathanbrauer.com/playground/plain-text/serialize-vs-json.php
さて、一つ注意すべきことは、array(1,2,3) は array(3,2,1) と異なる MD5 を生成することです。 もし の場合、これはあなたが望むものではありません。次のコードを試してみてください。
//Optionally make a copy of the array (if you want to preserve the original order)
$original = $array;
array_multisort($array);
$hash = md5(json_encode($array));
編集します。 順番を逆にしても同じ結果になるのではないかという疑問がありました。そこで、それを実行しました( 正しく )をここで行います。
- http://nathanbrauer.com/playground/json-vs-serialize.php
- http://nathanbrauer.com/playground/plain-text/json-vs-serialize.php
ご覧の通り、結果は全く同じです。 ここでは、( を修正しました。 ) テスト は Drupal に関係する人が作ったものです。 :
- http://nathanjbrauer.com/playground/drupal-calculation.php
- http://nathanjbrauer.com/playground/plain-text/drupal-calculation.php
そして、良い対策として、コピー&ペーストできる関数/メソッドを紹介します(5.3.3-1ubuntu9.5でテスト済み)。
function array_md5(Array $array) {
//since we're inside a function (which uses a copied array, not
//a referenced array), you shouldn't need to copy the array
array_multisort($array);
return md5(json_encode($array));
}
関連
-
[解決済み】php, mysql - データベースへの接続数が多すぎるエラー
-
[解決済み】PHPの予期しないT_VARIABLEとは何ですか?
-
[解決済み] SSLエラー SSL3_GET_SERVER_CERTIFICATE:証明書の検証に失敗しました。
-
[解決済み] PHPで配列から要素を削除する
-
[解決済み] Java の配列を表示する最も簡単な方法は何ですか?
-
[解決済み] 多次元配列の値によるソート方法
-
[解決済み] JavaScriptで2次元の配列を作成するにはどうすればよいですか?
-
[解決済み] PHP 配列をキーではなく値で削除する
-
[解決済み] PHP オブジェクトを連想配列に変換する
-
[解決済み] bcryptはどうして塩を内蔵しているのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】PHP - 構文エラー、予期しないT_CONSTANT_ECAPSED_STRING [閉店].
-
[解決済み] 整形されていない数値が発生しました。
-
[解決済み】 $_SERVER['DOCUMENT_ROOT'] と $_SERVER['HTTP_HOST'] の違いについて]
-
[解決済み】PHPからPythonスクリプトを実行する
-
[解決済み] [Solved] Fatal error: メンバ関数 query() の null への呼び出し。
-
[解決済み】PDOException SQLSTATE[HY000] [2002] そのようなファイルまたはディレクトリがありません。
-
[解決済み】In_arrayが動作しない。
-
[解決済み] mysql_field_nameを新しいmysqliに変更します。
-
[解決済み] $_SERVER['DOCUMENT_ROOT'] と $_SERVER['HTTP_HOST'] の違いについて
-
[解決済み] PHP の配列を保存するための好ましい方法 (json_encode vs serialize)