7
votes

Inverser une fonction de hachage

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;
}


2 commentaires

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


5 Réponses :


2
votes

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)


2 commentaires

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 .



8
votes

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());
}


5 commentaires

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 ());});


@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 pour satisfaire ces CRITERIA pour sa sortie, ou simplement que les chaînes que vous nourrissez dans hachage 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.



0
votes

Je démarrerais en écrivant chaque étape que résultat = ((résultat << 5) + résultat) + s [i]; 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).


2 commentaires

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.



2
votes

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> xxx pré>

Appelez-le avec: P>

char string[STRING_LENGTH + 1];
unhash(hash_value, string, 0);


0 commentaires

3
votes

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> xxx pré>

(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;


0 commentaires