<?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 ';
//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
';
echo 'json_encode is <strong>'.( round(($sTime/$jTime)*100,1) ).'%</strong> faster with a difference of <strong>'.($sTime-$jTime).' seconds</strong>';
现在,有一点需要注意的是,数组(1,2,3)将产生一个不同的MD5作为数组(3,2,1) . If 这不是你想要的 . 请尝试以下代码:
//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: 这里(正确地)完成了's been some question as to whether reversing the order would produce the same results. So, I':
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));
}
6
md5(serialize($array));
0
我通过回答加入了一个非常拥挤的聚会,但有一个重要的考虑因素是现存的答案都没有解决 . The value of json_encode() and serialize() both depend upon the order of elements in the array!
以下是 two arrays with identical values but added in a different order (帖子底部的代码)未对数组进行排序和排序的结果:
// You will need to write your own deep_ksort(), or see
// my example below
md5( serialize(deep_ksort($array)) );
md5( json_encode(deep_ksort($array)) );
json_encode() 或 serialize() 的选择应为 determined by testing on the type of data that you are using . 通过我自己对纯文本和数值数据的测试,如果代码没有运行数千次紧密循环,那么差异甚至不值得基准测试 . 我个人使用 json_encode() 来表示这种类型的数据 .
Here is the code used to generate the sorting test above:
My quick deep_ksort() implementation, fits this case but check it before using on your own projects:
/*
* Sort an array by keys, and additionall sort its array values by keys
*
* Does not try to sort an object, but does iterate its properties to
* sort arrays in properties
*/
function deep_ksort($input)
{
if ( !is_object($input) && !is_array($input) ) {
return $input;
}
foreach ( $input as $k=>$v ) {
if ( is_object($v) || is_array($v) ) {
$input[$k] = deep_ksort($v);
}
}
if ( is_array($input) ) {
ksort($input);
}
// Do not sort objects
return $input;
}
13 回答
请注意,
serialize
和json_encode
在键不以0开始的数字数组或关联数组时的行为方式不同 .json_encode
会将此类数组存储为Object
,因此json_decode
将返回Object
,其中unserialize
将返回具有完全相同键的数组 .我认为这可能是一个很好的提示:
(底部的复制粘贴功能)
如前所述,以下内容将起作用 .
但是,值得注意的是(具有讽刺意味的是)json_encode的执行速度明显更快:
事实上,速度增加在这里是两倍,因为(1)json_encode单独执行比串行化更快,(2)json_encode产生更小的字符串,因此md5处理更少 .
Edit: 以下是支持这一说法的证据:
JSON_ENCODE持续超过250%(2.5倍)(通常超过300%) - 这不是一个微不足道的差异 . 您可以在此处看到此实时脚本的测试结果:
http://nathanbrauer.com/playground/serialize-vs-json.php
http://nathanbrauer.com/playground/plain-text/serialize-vs-json.php
现在,有一点需要注意的是,数组(1,2,3)将产生一个不同的MD5作为数组(3,2,1) . If 这不是你想要的 . 请尝试以下代码:
Edit: 这里(正确地)完成了's been some question as to whether reversing the order would produce the same results. So, I':
http://nathanbrauer.com/playground/json-vs-serialize.php
http://nathanbrauer.com/playground/plain-text/json-vs-serialize.php
如您所见,结果完全相同 . 这是(更正的)测试originally created by someone related to Drupal:
http://nathanjbrauer.com/playground/drupal-calculation.php
http://nathanjbrauer.com/playground/plain-text/drupal-calculation.php
And for good measure, here's a function/method you can copy and paste (tested in 5.3.3-1ubuntu9.5):
我通过回答加入了一个非常拥挤的聚会,但有一个重要的考虑因素是现存的答案都没有解决 . The value of json_encode() and serialize() both depend upon the order of elements in the array!
以下是 two arrays with identical values but added in a different order (帖子底部的代码)未对数组进行排序和排序的结果:
因此,我建议 hash an array 的两种方法是:
json_encode()
或serialize()
的选择应为 determined by testing on the type of data that you are using . 通过我自己对纯文本和数值数据的测试,如果代码没有运行数千次紧密循环,那么差异甚至不值得基准测试 . 我个人使用json_encode()
来表示这种类型的数据 .Here is the code used to generate the sorting test above:
My quick deep_ksort() implementation, fits this case but check it before using on your own projects:
答案在很大程度上取决于数组值的数据类型 . 对于大字符串使用:
对于短字符串和整数使用:
4个内置的PHP函数可以将数组转换为字符串:serialize(),json_encode(),var_export(),print_r() .
在键和值中使用md5-hashes(32 char)测试多维数组的结果:
数值多维数组的测试结果:
关联数组test source . 数字数组test source .
除了Brock的优秀答案(1)之外,任何体面的散列库都允许您以增量方式更新散列,因此您应该能够按顺序更新每个字符串,而不必构建一个巨大的字符串 .
见:hash_update
将工作,但哈希将根据数组的顺序而改变(尽管可能无关紧要) .
关于
serialize()
的重要说明我不建议将其用作散列函数的一部分,因为它可以为以下示例返回不同的结果 . 检查以下示例:
简单的例子:
产生
但是以下代码:
输出:
因此,而不是第二个对象php只创建链接“r:2;”到第一个例子 . 这绝对是序列化数据的好方法,但它可能会导致散列函数出现问题 .
有几个答案告诉你使用json_code,
但是json_encode对iso-8859-1字符串不起作用,只要有一个特殊的字符串,字符串就会被裁剪 .
我建议使用var_export:
不像序列化那么慢,不像json_encode那样有问题
Currently the most up-voted answer md5(serialize($array)); doesn't work well with objects.
考虑代码:
尽管阵列是不同(它们包含不同的对象),它们在使用
md5(serialize($array));
时具有相同的哈希值 . 所以你的哈希是没用的!要避免该问题,可以在序列化之前替换结果为
spl_object_hash()
的对象 . 如果您的数组有多个级别,您也应该递归地执行此操作 .dotancohen建议,下面的代码也按键对数组进行排序 .
现在你可以使用
md5(serialize(replaceObjectsWithHashes($array)))
.(注意PHP中的数组是值类型 . 所以
replaceObjectsWithHashes
函数不要改变原始数组 . )我没有在上面看到解决方案,所以我想提供一个更简单的答案 . 对我来说,我使用相同的密钥,直到我使用ksort(密钥排序):
先用Ksort排序,然后在json_encode上执行sha1:
例:
输出更改的数组和哈希: