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

我可以很容易地编写一个循环,遍历数组的每一层,将每个值连接成一个字符串,然后简单地对字符串执行MD5.

然而,这看起来很麻烦,我想知道是否有一个时髦的函数可以接受多维数组,并对其进行散列.

推荐答案

(Copy-n-paste-able function at the bottom)

如前所述,以下步骤将起作用.

md5(serialize($array));

然而,值得注意的是(讽刺的是)json_encode执行速度快了noticeably倍:

md5(json_encode($array));

事实上,这里的速度提高了两倍,因为(1)单独使用json_encode执行的速度比序列化快,(2)json_encode生成的字符串更小,因此md5处理的时间更少.

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

<?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).这不是你想要的.请try 以下代码:

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

Edit:.有人质疑,颠倒顺序是否会产生同样的结果.我在这里做了(correctly):

正如你所见,结果完全相同.以下是(corrected)测试originally created by someone related to Drupal:

And for good measure, here's a function/method you can copy and paste (tested in 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相关问答推荐

WooCommerce基于元数据的自定义范围目录排序

ForHumans函数中的月当量与单位限制

在WooCommerce中禁用客户用户角色的纳税计算

根据产品类型显示或隐藏WooCommerce管理产品自定义字段

使用php创建表格和插入数据

在WooCommerce获取所有具有全球产品属性品牌的简单产品

WooCommerce短代码,显示特定产品的购物车徽章中的当前数量

Laravel服务Provider 没有向服务类注入价值

HTAccess重写一些URL,但将所有其他URL发送到另一个页面

向WooCommerce管理订单总额添加自定义总额行

Azure应用程序无法访问共享文件夹

Woocommerce 仅在前端为登录用户提供价格折扣

需要以一种形式执行两个操作

WooCommerce 回购自定义插件:如何更新用户钱包?

避免在 WooCommerce 中多次触发挂钩函数

Windows 身份验证在 IIS 中验证什么?我可以在我的情况下禁用匿名身份验证吗?

Composer自动加载器重复了子类的类文件路径

如何在 laravel 中的同一个 slug 上显示不同的内容?

使用循环和引用而不是递归创建分层/父子数组

如何在字符串constant-string-NUMBER-*中获取 NUMBER?