2010-10-29 5 views
11

Ho bisogno di eseguire l'hash di alcune stringhe in modo che sia possibile passarle in alcune librerie, questo è semplice utilizzando la chiamata String.hashCode.Convertire la stringa in hash e quindi riformare la stringa in seguito

Tuttavia, una volta che tutto è stato elaborato, mi piacerebbe convertire il numero intero generato da hashCode nel valore String. Potrei ovviamente tracciare i valori di stringhe e hashcode da qualche altra parte e fare la conversione lì, ma mi chiedo se ci sia qualcosa in Java che lo farà automaticamente.

+1

Per questo è possibile utilizzare la crittografia o la codifica/decodifica (forse base64). – jerjer

risposta

25

Penso che tu abbia frainteso il concetto di hash. Un hash è una funzione a senso unico. Peggio ancora, due stringhe potrebbero generare lo stesso hash.

Quindi no, non è possibile.

+1

In primo luogo, questo è il punto di un hash. –

7

Ciò non è possibile in generale. Lo hashCode è quello che si potrebbe chiamare uno one-way-function.

Inoltre, ci sono più stringhe degli interi, quindi esiste una mappatura uno-a-molti dagli interi alle stringhe. Le stringhe "0-42L" e "0-43-", ad esempio, hanno lo stesso codice hash. (Demonstration on ideone.com.)

cosa si potrebbe fare però, (come stima), dovrebbe essere quella di memorizzare le stringhe si passano nel API e ricordare i loro hash-codes come questo:

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'aggiunta a questo approccio potrebbe essere l'uso di BiDiMap (http://commons.apache.org/collections/api-3.1/org/apache/commons/collections/BidiMap.html) se è necessario fare ricerche inverse. Basta fare attenzione alle collisioni di hash .. :) – posdef

+0

Sarebbe meglio usare una mappa >. In questo modo puoi mappare gli hash alle stringhe corrispondenti in quanto possono essere multipli. – Carra

+0

Questo è un buon punto. Ma avrebbe comunque dovuto indovinare tra le stringhe 'Lista ' che corrispondeva a un certo codice hash. – aioobe

1

Non possibile convertire l'output .hashcode() nel modulo originale. È un processo a senso unico.

È possibile utilizzare uno base64 encoder scheme in cui codificare i dati, utilizzarlo dove si desidera e quindi decodificarlo nel modulo originale.

6

hashCode() non è in genere un bijection, perché in genere non sarà una mappa injective.

hashCode() ha come intervallo il int s. Ci sono solo 2^32 valori distinti int, quindi per qualsiasi oggetto in cui ci possono essere più di 2^32 diversi (ad esempio, pensare a Long), si è certi (dal pigeonhole principle che almeno due oggetti distinti avranno il stesso codice hash.

l'unica garanzia che hashCode() si dà è che se a.equals(b), quindi a.hashCode() == b.hashCode(). Ogni oggetto che ha lo stesso codice hash è coerente con questo.

È possibile utilizzare il hashCode() per identificare in modo univoco gli oggetti in alcune circostanze molto limitate: devi avere una classe particolare in cui non ci sono mor e di 2^32 possibili istanze diverse (cioè ci sono al massimo 2^32 oggetti della tua classe che a coppie sono tali che !a.equals(b)). In tal caso, fintanto che ci si assicura che ogni volta che !a.equals(b) ed entrambi a e sono oggetti della classe, che a.hashCode() != b.hashCode(), si avrà una biiezione tra (equivalenza classi di) oggetti e codici hash. (Potrebbe essere fatto in questo modo per la classe Integer, ad esempio.)

Tuttavia, a meno che tu non sia in questo caso molto speciale, dovresti creare un ID univoco in un altro modo.

+0

+1 per aver richiamato il principio del pigeonhole. – ArtOfWarfare

Problemi correlati