PHP对MD5多维数组的最佳方式?

2022-08-30 06:57:26

生成多维数组的 MD5(或任何其他哈希)的最佳方法是什么?

我可以很容易地编写一个循环,该循环将遍历数组的每个级别,将每个值连接成一个字符串,然后简单地在字符串上执行MD5。

但是,这似乎充其量很麻烦,我想知道是否有一个时髦的函数可以采用多维数组并进行哈希处理。


答案 1

(底部的可复制和粘贴功能)

如前所述,以下内容将起作用。

md5(serialize($array));

但是,值得注意的是,(具有讽刺意味的是)json_encode的性能明显更快:

md5(json_encode($array));

事实上,这里的速度提高了两倍,因为(1)单独json_encode比序列化执行得更快,并且(2)json_encode产生更小的字符串,因此md5处理的字符串更少。

编辑:以下是支持这一说法的证据:

<?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%) - 这不是一个微不足道的区别。您可以在此处使用此实时脚本看到测试结果:

现在,需要注意的一件事是数组(1,2,3)将生成一个不同的MD5作为数组(3,2,1)。如果这不是你想要的。请尝试以下代码:

//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));

编辑:对于反转订单是否会产生相同的结果,存在一些问题。所以,我在这里(正确地)做到了:

如您所见,结果完全相同。以下是最初由与Drupal相关的人创建的更正后的)测试:

为了更好地衡量,这里有一个可以复制和粘贴的函数/方法(在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));
}

答案 2
md5(serialize($array));