2010-10-29 8 views
11

J'ai besoin de hacher certaines chaînes pour pouvoir les passer dans certaines bibliothèques, ceci est simple en utilisant l'appel String.hashCode.Convertir une chaîne en hachage, puis réformer la chaîne plus tard

Cependant, une fois que tout est traité, je voudrais convertir l'entier généré à partir du hashCode dans la valeur String. Je pourrais évidemment suivre la chaîne et les valeurs de hashcode ailleurs et faire la conversion là-bas, mais je me demande s'il y a quelque chose en Java qui le fera automatiquement.

+1

Vous pouvez utiliser le cryptage ou l'encodage/décodage (peut-être base64) pour cela. – jerjer

Répondre

25

Je pense que vous avez mal compris le concept d'un hachage. Un hachage est une fonction à sens unique. Pire, deux chaînes peuvent générer le même hachage.

Donc non, ce n'est pas possible.

+1

D'ailleurs, c'est un peu le point d'un hachage en premier lieu. –

7

Ce n'est pas possible en général. Le hashCode est ce que l'on appelle un one-way-function. En outre, il existe plus de chaînes que d'entiers, il existe donc un mappage un-à-plusieurs des entiers vers les chaînes. Les chaînes "0-42L" et "0-43-" par exemple, ont le même code de hachage. (Demonstration on ideone.com.)

Ce que vous pouvez faire cependant (comme une estimation), serait de stocker les chaînes que vous passez dans l'API et se souvenir de leurs codes de hachage comme ceci:

import java.util.*; 

public class Main { 
    public static void main(String[] args) { 

     // Keep track of the corresponding strings 
     Map<Integer, String> hashedStrings = new HashMap<Integer, String>(); 

     String str1 = "hello"; 
     String str2 = "world"; 

     // Compute hash-code and remember which string that gave rise to it. 
     int hc = str1.hashCode(); 
     hashedStrings.put(hc, str1); 

     apiMethod(hc); 

     // Get back the string that corresponded to the hc hash code. 
     String str = hashedStrings.get(hc); 
    } 
} 
+0

un complément à cette approche pourrait être d'utiliser BiDiMap (http://commons.apache.org/collections/api-3.1/org/apache/commons/collections/BidiMap.html) si vous avez besoin de faire des recherches inversées. Méfiez-vous simplement des collisions de hachage .. :) – posdef

+0

Il serait préférable d'utiliser une carte >. De cette façon, vous pouvez mapper vos hachages aux chaînes correspondantes, car elles peuvent être multiples. – Carra

+0

C'est un bon point. Mais il aurait encore à deviner parmi les chaînes 'Liste ' qui correspondait à un certain code de hachage. – aioobe

1

Pas possible pour convertir la sortie .hashcode() en formulaire d'origine. C'est un processus à sens unique.

Vous pouvez utiliser un base64 encoder scheme où vous allez encoder les données, les utiliser où vous le souhaitez, puis les décoder dans le formulaire d'origine.

6

hashCode() n'est généralement pas un bijection, car il ne s'agit généralement pas d'une carte injective.

hashCode() a int s comme sa gamme. Il n'y a que 2^32 valeurs distinctes int, donc pour tout objet où il peut y avoir plus de 2^32 différentes (par exemple, pensez à Long), vous êtes garanti (par le pigeonhole principle qu'au moins deux objets distincts auront le même code de hachage.

la seule garantie que hashCode() vous donne est que si a.equals(b), puis a.hashCode() == b.hashCode(). Chaque objet ayant le même code de hachage est conforme à ce sujet.

vous peut utiliser le hashCode() pour identifier des objets dans certaines circonstances très limitées: Vous devez avoir une classe particulière dans laquelle il n'y a pas de e que 2^32 instances différentes possibles (c'est-à-dire, il y a au plus 2^32 objets de votre classe qui sont par paires tels que !a.equals(b)). Dans ce cas, tant que vous vous assurez que lorsque !a.equals(b) et a et b sont des objets de votre classe, que a.hashCode() != b.hashCode(), vous aurez une bijection entre (classes d'équivalences) et les codes de hachage. (Cela peut être fait comme ceci pour la classe Integer, par exemple.)

Cependant, à moins que vous ne soyez dans ce cas très spécial, vous devriez créer un identifiant unique d'une autre manière.

+0

+1 pour élever le principe du pigeonnier. – ArtOfWarfare