2011-04-06 20 views
31

Me preguntaba ¿cuál sería la forma más fácil de convertir un UUID en un número entero único? He intentado usar el código hash pero la gente me dice que no siempre será único si utilizo el código hash.UUID a la identificación entera única?

Entonces, ¿cuál es la manera más fácil? ¿Es el código hash único?

+0

No, no es, por definición. Además, si fuera único, ¿por qué alguien necesitaría UUID? – Ingo

+0

Definir único. ¿Globalmente, o solo dentro de su aplicación, o un poco de código? –

+0

Es solo que por alguna tonta especificación necesité un entero único de la aplicación, quería hacer uso de la clase UUID, pero resulta que no puedo bajar de escala. –

Respuesta

24

Va a tener un problema ya que el UUID es de 128 bits y el int es de solo 32 bits. Deberá aceptar el riesgo de colisiones e intentar cambiarlo por un espacio más pequeño (hashCode es probablemente una buena manera de hacerlo) o buscar una alternativa (use el UUID directamente, asigne un BigInteger - difícil de decir sin saber por qué)

+3

hashCode es lo que necesito. Para mi caso, necesito pasar un int como NotificationId a NotificationManager de Android. Puedo tolerar la colisión de esas notificaciones. – tmin

2

No, el código hash no es (y no puede ser) único. Lo que pasa con un GUID/UUID es que necesita todos los 128 bits para garantizar la exclusividad, por lo que reducirlo de algún modo generará problemas, como p. GUIDs are globally unique, but substrings of GUIDs aren't.

Honestamente, creo que es mejor usar solo enteros secuenciales y omitir el GUID por completo. Si necesita GUID por algún motivo, utilícelos y no intente generar un número entero a partir de ellos.

+3

Comentarios: 1) El código hash puede ser único. Tu no sabes [Sin embargo, no confíe en él] (http://security.stackexchange.com/a/52881/94827). 2) No tienes garantía de la singularidad de UUID. Solo una muy buena probabilidad de nunca ver una colisión. 3) Incluso si lo hizo "reduciéndolo de cualquier manera", no crea necesariamente ningún problema. Aumenta el riesgo de colisiones, sí, y debe ser consciente de las consecuencias de romper el estándar UUID, pero eso puede estar perfectamente bien en algunas situaciones. 4) El enlace está muerto. – Zero3

1

Un UUID es un número de 16 bytes (128 bit). No puede reducirlo a int (32 bit) conservando su singularidad.

Matemáticamente hablado: 2 UUID compartirán el mismo valor hash -tamaño Java int (que es mucho ...;))

Una salida - algunos UUID vida real a menudo tienen un lugar parte estática Por lo tanto, en escenarios aislados, la parte real única de los UUID puede ser inferior a 32 bits.

9

Respondiendo a la ¿Cómo puedo tener una aplicación única de ancho Entero:

Si tiene que ser único, incluso después de reinicios o si está agrupado que la aplicación se puede utilizar una secuencia de bases de datos.

Si solo tiene que ser exclusivo durante el tiempo de ejecución, utilice un estático AtomicInteger.

EDIT (ejemplo añadido):

public class Sequence { 

    private static final AtomicInteger counter = new AtomicInteger(); 

    public static int nextValue() { 
    return counter.getAndIncrement(); 
    } 
} 

Uso:

int nextValue = Sequence.nextValue(); 

Esto es hilo de seguridad (diferentes hilos siempre recibirán valores distintos, y no hay valores serán "perdido")

+0

¿Puede darme un ejemplo de cómo usar AtomicInteger? –

+1

El uso debe ser editado; muestra "Counter.nextValue();", pero la clase se llama "Sequence" –

+0

Este uso solo puede ser usado por un solo jvm, el clúster (varios jvms) no podría usar esta opción. –

Cuestiones relacionadas