Hasher un objet Json

Le
Julien Arlandis
Bonsoir,

J'ai besoin d'une fonction qui permet de hasher un objet json, bien sûr
le résultat du hash ne doit pas dépendre de l'ordre des listes.
Par exemple, ces deux objets json
$json = <<<EOF
{
"tttt" : ["hdfhdf","jjj", "2"],
"lll" : "ppppppppppppp",
"aaa" :
{
"jjj" :
{
"aaaaaaa" : "oooo",
"sssss" : "llll"
},
"ccc" : "ooo"
},
"bbb" : "xxxxx"
}
EOF;

et

$json = <<<EOF
{
"aaa" :
{
"ccc" : "ooo",
"jjj" :
{
"sssss" : "llll",
"aaaaaaa" : "oooo"
},
},
"lll" : "ppppppppppppp",
"tttt" : ["hdfhdf","jjj", "2"],
"bbb" : "xxxxx"
}
EOF;

sont identiques, ils doivent donc avoir le même hash sha1.

J'ai donc écrit 2 petites fonctions :

// Transforme l'onbjet json en un tableau ordonné
function json2array($json, $prefix = "")
{
static $tab = array();
foreach ($json as $cle => $value)
{

$cle = $prefix."/".str_replace("/", "//", $cle);
if(is_object($value))
{
json2array($value, $cle);
}
elseif(is_array($value))
{
$i = 0;
foreach($value as $val)
{
$tab[$cle."/".$i] = (string) $val;
$i++;
}
}
else
{
$tab[$cle] = (string) $value;
}
}

ksort($tab);
return $tab;
}


// Applique un hash sur chaque clé, valeur du tableau concatène le tout,
et applique un hash.
function getHash($json)
{
$tab = json2array($json);
$long_hash = "";
foreach($tab as $cle => $value)
{
$long_hash .= sha1($cle).sha1($value);
}

return sha1($long_hash);
}


Pour obtenir mon hash j'appele la fonction
$json = json_decode($json);
getHash($json);
et j'obtiens bien "edfeed3410bbc567fdc73154baf3a5d30b4f8bd3" pour les
deux chaines.

Mon soucis c'est que j'ai deux fonctions, et j'aimerais en avoir qu'une
seule. J'aimerais bien faire rentrer json2array() dans getHash() mais à
cause de la récursivité dans la fonction json2array je ne sais pas
comment m'y prendre.
Une astuce, une idée?

PS : crosspost sur fr.comp.securite pour détecter une éventuelle
faiblesse dans la façon de hasher mon objet.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Antoine Polatouche
Le #25351202
Le 15/04/2013 21:28, Julien Arlandis a écrit :
Pour obtenir mon hash j'appele la fonction
$json = json_decode($json);
getHash($json);
et j'obtiens bien "edfeed3410bbc567fdc73154baf3a5d30b4f8bd3" pour les
deux chaines.

Mon soucis c'est que j'ai deux fonctions, et j'aimerais en avoir qu'une
seule. J'aimerais bien faire rentrer json2array() dans getHash() mais à
cause de la récursivité dans la fonction json2array je ne sais pas
comment m'y prendre.
Une astuce, une idée?



Bonjour,

en utilisant les classes de php, tu peux faire une méthode statique
maClasse::getHash($json), pour avoir ce qui ressemble le plus à une
fonction, ou utiliser des méthodes publiques, genre
$obj = new maClasse($json);
$obj->getHash();

Dans les deux cas, la fonction récursive est encapsulée dans la classe.

Ça va si tu mets le code de la classe dans un fichier séparé, mais si
c'est pour mettre tout le code dans le même fichier, ça n'arrange pas
ton problème: tu as une classe en plus au lieu d'une fonction en plus ;)
Publicité
Poster une réponse
Anonyme