J'ai la fonction de hachage suivante, et j'essaie de mettre le moyen de l'inverser, de sorte que je puisse trouver la clé d'une valeur hachée.
uint Hash(string s)
{
uint result = 0;
for (int i = 0; i < s.Length; i++)
{
result = ((result << 5) + result) + s[i];
}
return result;
}
5 Réponses :
Les fonctions de hachage sont conçues pour être difficiles ou impossibles à inverser, d'où le nom (visualisez la viande + des pommes de terre étant broyées) p>
Je vais maintenant me sentir faim à chaque fois que j'utilise un dictionnaire!
Si c'est la véritable étymologie du mot "hachage" comme cela concerne l'informatique (je ne sais pas, car je n'ai pas de fond académique dedans) ... Eh bien, c'est génial b>.
Ceci devrait inverser les opérations:
string Unhash(uint hash)
{
List<char> s = new List<char>();
while (hash != 0)
{
s.Add((char)(hash % 33));
hash /= 33;
}
s.Reverse();
return new string(s.ToArray());
}
Eh bien, cela ne fonctionne pas, car je pense qu'il existe une somme de résultat dans chaque itération, il existe également d'autres contraintes, cette fonction n'accepte que 0 à 9 et '*' et '#' dans son entrée, voir la modification ci-dessus: )
+1. Ça marche pour moi. Voici un test (C # 4.0 requis) -> parallel.for (uint.minvalue, uint.maxvalue, couranteValue => {debug.assert (hachage (panne (malhum ((UINT)) == Coururvalue, "Échec du test : "+ courantvalue.tostring ());}); code>
@Merlyn Morgan-Graham Oui, le décodage est correct, mais j'ai besoin de la valeur pour contenir uniquement des chiffres 0 à 9 et '*' et '#' car la seule possibilité d'entrée est sur un téléphone
@Martani_net: Votre question est ambiguë pour que vous ayez besoin de votre fonction indash code> pour satisfaire ces CRITERIA pour sa sortie, ou simplement que les chaînes que vous nourrissez dans hachage code> les rencontrerait . Notez que vous pouvez toujours exécuter mon test sur l'un ou l'autre type de solution.
@Merlyn Morgan-Graham Droite, je viens de corriger la question, la fonction panneaux doit également répondre à ces critères.
Je démarrerais en écrivant chaque étape que résultat = ((résultat << 5) + résultat) + s [i]; code> sur une ligne distincte. Cela fera la résolution beaucoup plus facile. Ensuite, tout ce que vous avez à faire est le contraire de chaque ligne (dans l'ordre inverse aussi). P>
Je l'ai fait, mais le problème est que vous n'avez pas le dernier personnage pour commencer!
Et vous ne le ferez jamais, vous devez donc sauter cela.
La force brute devrait fonctionner si Uint est de 32 bits. Essayez au moins 2 ^ 32 cordes et l'un d'entre eux est susceptible de hacher à la même valeur. Ne devrait prendre que quelques minutes sur un PC moderne.
Vous avez 12 caractères possibles et 12 ^ 9 est d'environ 2 ^ 32, donc si vous essayez 9 chaînes de caractères, vous êtes susceptible de trouver votre hachage cible. Je ferai 10 cordes de caractères juste pour être en sécurité. P>
(implémentation récursive simple en C ++, ne sais pas C # aussi bien) p> Appelez-le avec: P> char string[STRING_LENGTH + 1];
unhash(hash_value, string, 0);
caractères 0-9, *, # avoir des valeurs ASCII 48-57,42,35 ou binaire: 00110000 ... 00111001, 00101010, 00100011
Les 5 premiers bits de ces valeurs sont différents et 6ème bit est Toujours 1. Cela signifie que vous pouvez déduire votre dernier caractère dans une boucle en prenant un hachage actuel: p> (si cela ne fonctionne pas, je ne sais pas qui a écrit qui a écrit IT) P> Roulez maintenant HASH, P> hash = (hash - lastChar) / 33;
Y a-t-il une limite à la longueur de la chaîne qui est entrée?
Pas un devoir, et je suppose que la limite ne dépasse pas une douzaine de caractères