(Função de copiar e colar na parte inferior)
Conforme mencionado anteriormente, o seguinte funcionará.
md5(serialize($array));
No entanto, é importante notar que (ironicamente) json_encode tem um desempenho visivelmente mais rápido:
md5(json_encode($array));
Na verdade, o aumento de velocidade é duplo aqui, já que (1) json_encode sozinho executa mais rápido do que serializar e (2) json_encode produz uma string menor e, portanto, menos para o md5 manipular.
Edit: Aqui estão as evidências para apoiar esta afirmação:
<?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 é consistentemente mais de 250% (2,5x) mais rápido (frequentemente mais de 300%) - esta não é uma diferença trivial. Você pode ver os resultados do teste com este script ao vivo aqui:
Agora, uma coisa a se notar é que array (1,2,3) produzirá um MD5 diferente como array (3,2,1). Se NÃO é isso que você deseja. Experimente o seguinte 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));
Edit: Tem havido alguma dúvida sobre se inverter a ordem produziria os mesmos resultados. Então, eu fiz isso ( corretamente ) aqui:
Como você pode ver, os resultados são exatamente os mesmos. Aqui está o teste ( corrigido ) originalmente criado por alguém relacionado ao Drupal :
E para uma boa medida, aqui está uma função / método que você pode copiar e colar (testado em 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)
(o cálculo anterior está obviamente incorreto). Meu array tem até 2 níveis de profundidade, então lembre-se de que (como sempre) sua milhagem pode variar.fonte
Estou entrando em uma festa muito lotada respondendo, mas há uma consideração importante que nenhuma das respostas existentes aborda. O valor de
json_encode()
eserialize()
ambos dependem da ordem dos elementos no array!Aqui estão os resultados de não classificar e classificar os arrays, em dois arrays com valores idênticos, mas adicionados em uma ordem diferente (código na parte inferior da postagem) :
Portanto, os dois métodos que eu recomendaria para fazer o hash de uma matriz seriam:
A escolha de
json_encode()
ouserialize()
deve ser determinada testando o tipo de dados que você está usando . Pelos meus próprios testes em dados puramente textuais e numéricos, se o código não estiver executando um loop restrito milhares de vezes, a diferença nem vale a pena ser comparada. Eu pessoalmente usojson_encode()
para esse tipo de dados.Aqui está o código usado para gerar o teste de classificação acima:
Minha implementação rápida de deep_ksort () se encaixa neste caso, mas verifique antes de usar em seus próprios projetos:
fonte
A resposta depende muito dos tipos de dados dos valores da matriz. Para cordas grandes, use:
Para strings curtas e inteiros, use:
4 funções embutidas do PHP podem transformar array em string: serialize () , json_encode () , var_export () , print_r () .
Resultados do teste para matriz multidimensional com hashes md5 (32 caracteres) em chaves e valores:
Resultado do teste para matriz multidimensional numérica:
Fonte de teste de matriz associativa . Fonte de teste de matriz numérica .
fonte
Além da excelente resposta de Brock (+1), qualquer biblioteca de hash decente permite que você atualize o hash em incrementos, então você deve ser capaz de atualizar cada string sequencialmente, ao invés de ter que construir uma string gigante.
Vejo:
hash_update
fonte
Funcionará, mas o hash mudará dependendo da ordem do array (isso pode não importar).
fonte
Observe isso
serialize
ejson_encode
aja de maneira diferente quando se trata de matrizes numéricas em que as chaves não começam em 0 ou de matrizes associativas.json_encode
irá armazenar tais arrays como umObject
, entãojson_decode
retorna umObject
, ondeunserialize
irá retornar um array com exatamente as mesmas chaves.fonte
Acho que essa poderia ser uma boa dica:
fonte
Nota importante sobre
serialize()
Eu não recomendo usá-lo como parte da função de hashing porque ele pode retornar resultados diferentes para os exemplos a seguir. Veja o exemplo abaixo:
Exemplo simples:
Produz
Mas o seguinte código:
Resultado:
Portanto, em vez do segundo objeto php, apenas crie o link "r: 2;" para a primeira instância. É definitivamente uma maneira boa e correta de serializar dados, mas pode levar a problemas com sua função de hashing.
fonte
fonte
existem várias respostas dizendo para usar json_code,
mas json_encode não funciona bem com a string iso-8859-1, assim que houver um caractere especial, a string é cortada.
eu aconselharia usar var_export:
não tão lento quanto serializar, não tão bugado quanto json_encode
fonte
Atualmente, a resposta mais votada
md5(serialize($array));
não funciona bem com objetos.Considere o código:
Mesmo que os arrays sejam diferentes (eles contêm objetos diferentes), eles têm o mesmo hash quando usados
md5(serialize($array));
. Então seu hash é inútil!Para evitar esse problema, você pode substituir os objetos com o resultado de
spl_object_hash()
antes de serializar. Você também deve fazer isso recursivamente se sua matriz tiver vários níveis.O código abaixo também classifica os arrays por chaves, como sugerido pelo dotancohen.
Agora você pode usar
md5(serialize(replaceObjectsWithHashes($array)))
.(Observe que a matriz em PHP é o tipo de valor. Portanto, a
replaceObjectsWithHashes
função NÃO altere a matriz original.)fonte
Não vi a solução acima tão facilmente, então queria contribuir com uma resposta mais simples. Para mim, eu estava recebendo a mesma chave até usar ksort (classificação de chave):
Ordenado primeiro com Ksort, em seguida, executado sha1 em um json_encode:
exemplo:
Saída de matrizes e hashes alterados:
fonte