(Fonction copier-coller en bas)
Comme mentionné précédemment, ce qui suit fonctionnera.
md5(serialize($array));
Cependant, il convient de noter que (ironiquement) json_encode fonctionne sensiblement plus rapidement:
md5(json_encode($array));
En fait, l'augmentation de la vitesse est double ici car (1) json_encode seul est plus rapide que sérialiser, et (2) json_encode produit une chaîne plus petite et donc moins à gérer pour md5.
Edit: Voici des preuves à l'appui de cette affirmation:
<?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 est systématiquement plus de 250% (2,5x) plus rapide (souvent plus de 300%) - ce n'est pas une différence anodine. Vous pouvez voir les résultats du test avec ce script en direct ici:
Maintenant, une chose à noter est que array (1,2,3) produira un MD5 différent en tant que array (3,2,1). Si ce n'est PAS ce que vous voulez. Essayez le code suivant:
//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: On s'est demandé si l'inversion de l'ordre produirait les mêmes résultats. Donc, je l'ai fait ( correctement ) ici:
Comme vous pouvez le voir, les résultats sont exactement les mêmes. Voici le test ( corrigé ) créé à l'origine par une personne liée à Drupal :
Et pour faire bonne mesure, voici une fonction / méthode que vous pouvez copier et coller (testée dans 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)
(le calcul précédent est évidemment incorrect). Mon tableau a jusqu'à 2 niveaux de profondeur, alors gardez simplement à l'esprit que (comme d'habitude) votre kilométrage peut varier.la source
Je me joins à un groupe très fréquenté en répondant, mais il y a une considération importante qu'aucune des réponses existantes n'aborde. La valeur de
json_encode()
et lesserialize()
deux dépendent de l'ordre des éléments dans le tableau!Voici les résultats de ne pas trier et trier les tableaux, sur deux tableaux avec des valeurs identiques mais ajoutés dans un ordre différent (code en bas de l'article) :
Par conséquent, les deux méthodes que je recommanderais pour hacher un tableau seraient:
Le choix de
json_encode()
ouserialize()
doit être déterminé en testant le type de données que vous utilisez . D'après mes propres tests sur des données purement textuelles et numériques, si le code n'exécute pas une boucle serrée des milliers de fois, la différence ne vaut même pas la peine d'être comparée. J'utilise personnellementjson_encode()
pour ce type de données.Voici le code utilisé pour générer le test de tri ci-dessus:
Ma mise en œuvre rapide de deep_ksort () convient à ce cas, mais vérifiez-la avant de l'utiliser sur vos propres projets:
la source
La réponse dépend fortement des types de données des valeurs de tableau. Pour les grosses cordes, utilisez:
Pour les chaînes courtes et les entiers, utilisez:
4 fonctions PHP intégrées peuvent transformer un tableau en chaîne: serialize () , json_encode () , var_export () , print_r () .
Résultats des tests pour un tableau multidimensionnel avec des hachages md5 (32 caractères) dans les clés et les valeurs:
Résultat du test pour un tableau multidimensionnel numérique:
Source de test de tableau associatif . Source de test de tableau numérique .
la source
Outre l'excellente réponse de Brock (+1), toute bibliothèque de hachage décente vous permet de mettre à jour le hachage par incréments, vous devriez donc pouvoir mettre à jour chaque chaîne de manière séquentielle, au lieu de devoir créer une chaîne géante.
Voir:
hash_update
la source
Cela fonctionnera, mais le hachage changera en fonction de l'ordre du tableau (cela n'a peut-être pas d'importance).
la source
Notez cela
serialize
etjson_encode
agissez différemment lorsqu'il s'agit de tableaux numériques où les clés ne commencent pas à 0, ou de tableaux associatifs.json_encode
stockera ces tableaux sous forme deObject
, doncjson_decode
renvoie unObject
, oùunserialize
retournera un tableau avec exactement les mêmes clés.la source
Je pense que cela pourrait être un bon conseil:
la source
Remarque importante sur
serialize()
Je ne recommande pas de l'utiliser dans le cadre de la fonction de hachage car il peut renvoyer des résultats différents pour les exemples suivants. Consultez l'exemple ci-dessous:
Exemple simple:
Produit
Mais le code suivant:
Production:
Donc, au lieu du deuxième objet php, créez simplement le lien "r: 2;" à la première instance. C'est certainement un bon moyen de sérialiser les données, mais cela peut entraîner des problèmes avec votre fonction de hachage.
la source
la source
il y a plusieurs réponses indiquant d'utiliser json_code,
mais json_encode ne fonctionne pas correctement avec la chaîne iso-8859-1, dès qu'il y a un caractère spécial, la chaîne est rognée.
je conseillerais d'utiliser var_export:
pas aussi lent que sérialiser, pas aussi bogué que json_encode
la source
Actuellement, la réponse la plus votée
md5(serialize($array));
ne fonctionne pas bien avec les objets.Considérez le code:
Même si les tableaux sont différents (ils contiennent des objets différents), ils ont le même hachage lors de l'utilisation
md5(serialize($array));
. Donc votre hash est inutile!Pour éviter ce problème, vous pouvez remplacer les objets par le résultat
spl_object_hash()
avant la sérialisation. Vous devez également le faire de manière récursive si votre tableau a plusieurs niveaux.Le code ci-dessous trie également les tableaux par clés, comme l'ont suggéré dotancohen.
Vous pouvez maintenant utiliser
md5(serialize(replaceObjectsWithHashes($array)))
.(Notez que le tableau en PHP est de type valeur. Donc, la
replaceObjectsWithHashes
fonction NE change PAS le tableau d'origine.)la source
Je n'ai pas vu la solution si facilement ci-dessus, je voulais donc apporter une réponse plus simple. Pour moi, j'obtenais la même clé jusqu'à ce que j'utilise ksort (tri de clé):
Trié d'abord avec Ksort, puis effectué sha1 sur un json_encode:
exemple:
Sortie de tableaux et de hachages modifiés:
la source