2010-10-29 11 views
11

Necesito hash algunas cadenas para que pueda pasarlas a algunas bibliotecas, esto es sencillo utilizando la llamada String.hashCode.Convierte cadena a hash y luego reforma la cadena más tarde

Sin embargo, una vez que todo se haya procesado, me gustaría convertir el entero generado a partir del hashCode en el valor String. Obviamente, podría rastrear los valores de cadena y hashcode en otro lugar y hacer la conversión allí, pero me pregunto si hay algo en Java que lo haga automáticamente.

+1

Puede usar cifrado o codificación/decodificación (tal vez base64) para esto. – jerjer

Respuesta

25

Creo que malinterpretas el concepto de hash. Un hash es una función de una sola dirección. Peor aún, dos cadenas podrían generar el mismo hash.

Así que no, no es posible.

+1

Además, ese es el punto de un hash en primer lugar. –

7

Eso no es posible en general. El hashCode es lo que uno llamaría one-way-function.

Además, hay más cadenas que enteros, por lo que hay un mapeo uno a muchos desde enteros a cadenas. Las cadenas "0-42L" y "0-43-", por ejemplo, tienen el mismo código hash. (Demonstration on ideone.com.)

Lo que podría hacer sin embargo, (como una estimación), sería la de almacenar las cadenas que pasan a la API y recordar sus hash códigos de la siguiente manera:

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

una adición a este enfoque podría ser utilizar BiDiMap (http://commons.apache.org/collections/api-3.1/org/apache/commons/collections/BidiMap.html) si necesita realizar búsquedas inversas. Solo tenga cuidado con las colisiones hash ... :) – posdef

+0

Sería mejor usar un Mapa >. De esta forma, puede asignar sus valores hash a las cadenas correspondientes, ya que pueden ser múltiples. – Carra

+0

Ese es un buen punto. Pero aún tendría que adivinar entre las cadenas 'List ' que correspondía a un cierto código hash. – aioobe

1
No

posible para convertir la salida .hashcode() a la forma original. Es un proceso de una sola dirección.

Puede usar un base64 encoder scheme donde codificará los datos, úselos donde quiera y decodifíquelos a su forma original.

6

hashCode() generalmente no va a ser un bijection, porque generalmente no va a ser un mapa injective.

hashCode() tiene int s como su rango. Solo hay 2^32 valores distintos de int, por lo que para cualquier objeto donde haya más de 2^32 diferentes (por ejemplo, piense en Long), está garantizado (por el pigeonhole principle que al menos dos objetos distintos tendrán la mismo código hash.

la única garantía de que hashCode() que da es que si a.equals(b), entonces a.hashCode() == b.hashCode(). Cada objeto que tiene el mismo código hash es consistente con esto.

usted puede utilizar el hashCode() para identificar los objetos en algunas circunstancias muy limitadas: debe tener una clase particular en donde no haya más e de 2^32 posibles instancias diferentes (es decir, hay a lo sumo 2^32 objetos de su clase que por pares son tales que !a.equals(b)). En ese caso, siempre y cuando se asegure de que cada vez que !a.equals(b) y a y b sean objetos de su clase, ese a.hashCode() != b.hashCode(), tendrá una biyección entre (clases de equivalencia de) objetos y códigos hash. (Podría hacerse así para la clase Integer, por ejemplo).

Sin embargo, a menos que esté en este caso tan especial, debe crear una identificación única de otra manera.

+0

+1 para mencionar el principio del casillero. – ArtOfWarfare

Cuestiones relacionadas