(Función copiar y pegar en la parte inferior)
Como se mencionó anteriormente, lo siguiente funcionará.
md5(serialize($array));
Sin embargo, vale la pena señalar que (irónicamente) json_encode funciona notablemente más rápido:
md5(json_encode($array));
De hecho, el aumento de velocidad es el doble aquí ya que (1) json_encode solo funciona más rápido que serializar, y (2) json_encode produce una cadena más pequeña y por lo tanto menos para que md5 la maneje.
Editar: Aquí hay evidencia para respaldar esta afirmación:
<?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 es consistentemente más de 250% (2.5x) más rápido (a menudo más de 300%); esta no es una diferencia trivial. Puede ver los resultados de la prueba con este script en vivo aquí:
Ahora, una cosa a tener en cuenta es que la matriz (1,2,3) producirá un MD5 diferente como matriz (3,2,1). Si esto NO es lo que quieres. Prueba el siguiente código:
//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));
Editar: Ha habido algunas dudas sobre si invertir el orden produciría los mismos resultados. Entonces, lo he hecho ( correctamente ) aquí:
Como puede ver, los resultados son exactamente los mismos. Aquí está la prueba ( corregida ) creada originalmente por alguien relacionado con Drupal :
Y en buena medida, aquí hay una función / método que puede copiar y pegar (probado en 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));
}
serialize() w/ md5() took: 0.27773594856262 sec
json_encode() w/ md5() took: 0.34809803962708 sec
json_encode is (79.8%) faster with a difference of (-0.070362091064453 seconds)
(el cálculo anterior es obviamente incorrecto). Mi matriz tiene hasta 2 niveles de profundidad, así que tenga en cuenta que (como de costumbre) su kilometraje puede variar.fuente
Me uniré a una fiesta muy concurrida al responder, pero hay una consideración importante que ninguna de las respuestas existentes aborda. ¡El valor de
json_encode()
yserialize()
ambos dependen del orden de los elementos en la matriz!Estos son los resultados de no ordenar y ordenar las matrices, en dos matrices con valores idénticos pero agregadas en un orden diferente (código en la parte inferior de la publicación) :
Por lo tanto, los dos métodos que recomendaría para hacer hash en una matriz serían:
La elección del
json_encode()
oserialize()
debe ser determinado por las pruebas del tipo de datos que se está utilizando . Según mis propias pruebas con datos puramente textuales y numéricos, si el código no se ejecuta en un bucle cerrado miles de veces, la diferencia ni siquiera vale la pena compararla. Yo personalmente usojson_encode()
para ese tipo de datos.Aquí está el código utilizado para generar la prueba de clasificación anterior:
Mi implementación rápida de deep_ksort (), se ajusta a este caso, pero compruébalo antes de usarlo en tus propios proyectos:
fuente
La respuesta depende en gran medida de los tipos de datos de los valores de matriz. Para cuerdas grandes use:
Para cadenas cortas y enteros use:
4 funciones PHP integradas pueden transformar una matriz en una cadena: serialize () , json_encode () , var_export () , print_r () .
Resultados de la prueba para una matriz multidimensional con md5-hashes (32 caracteres) en claves y valores:
Resultado de la prueba para una matriz numérica multidimensional:
Fuente de prueba de matriz asociativa . Fuente de prueba de matriz numérica .
fuente
Aparte de la excelente respuesta de Brock (+1), cualquier biblioteca de hash decente le permite actualizar el hash en incrementos, por lo que debería poder actualizar con cada cadena secuencialmente, en lugar de tener que construir una cadena gigante.
Ver:
hash_update
fuente
Funcionará, pero el hash cambiará según el orden de la matriz (aunque puede que no importe).
fuente
Tenga en cuenta eso
serialize
yjson_encode
actúe de manera diferente cuando se trata de matrices numéricas donde las claves no comienzan en 0, o matrices asociativas.json_encode
almacenará tales matrices como anObject
, por lo quejson_decode
devuelve anObject
, dondeunserialize
devolverá una matriz con exactamente las mismas claves.fuente
Creo que este podría ser un buen consejo:
fuente
Nota importante sobre
serialize()
No recomiendo usarlo como parte de la función hash porque puede devolver un resultado diferente para los siguientes ejemplos. Mira el ejemplo a continuación:
Ejemplo simple:
Produce
Pero el siguiente código:
Salida:
Entonces, en lugar del segundo objeto php, simplemente cree el enlace "r: 2;" a la primera instancia. Definitivamente es una forma buena y correcta de serializar datos, pero puede provocar problemas con la función hash.
fuente
fuente
hay varias respuestas que dicen usar json_code,
pero json_encode no funciona bien con la cadena iso-8859-1, tan pronto como hay un carácter especial, la cadena se recorta.
Aconsejaría usar var_export:
no tan lento como serializar, no tan bug como json_encode
fuente
Actualmente, la respuesta más votada
md5(serialize($array));
no funciona bien con objetos.Considere el código:
Aunque las matrices son diferentes (contienen diferentes objetos), tienen el mismo hash cuando se usan
md5(serialize($array));
. ¡Entonces tu hachís es inútil!Para evitar ese problema, puede reemplazar objetos con el resultado de
spl_object_hash()
antes de serializar. También debe hacerlo de forma recursiva si su matriz tiene varios niveles.El código siguiente también ordena las matrices por claves, como sugirió dotancohen.
Ahora puedes usar
md5(serialize(replaceObjectsWithHashes($array)))
.(Tenga en cuenta que la matriz en PHP es de tipo valor. Por lo tanto, la
replaceObjectsWithHashes
función NO cambia la matriz original).fuente
No vi la solución tan fácilmente arriba, así que quería contribuir con una respuesta más simple. Para mí, obtenía la misma clave hasta que usé ksort (clasificación de clave):
Ordenado primero con Ksort, luego realizado sha1 en un json_encode:
ejemplo:
Salida de matrices y hashes alterados:
fuente