¿Alguien ha hecho alguna investigación real sobre la probabilidad de colisiones de UUID, especialmente con UUID de versión 4 (aleatorio), dado que los generadores de números aleatorios que utilizamos no son realmente aleatorios y que podríamos tener docenas o cientos de máquinas idénticas que ejecutan el mismo código generando UUID?
Mis compañeros de trabajo consideran que la prueba de colisión UUID es una pérdida de tiempo completa, pero siempre pongo el código para detectar una excepción de clave duplicada de la base de datos e intentar nuevamente con un nuevo UUID. Pero eso no va a resolver el problema si el UUID proviene de otro proceso y se refiere a un objeto real.
NEWID()
función no es aleatoria? Si es así, ¿tiene alguna fuente para respaldar tal reclamo? Su salida se ve claramente como v4 UUID para mí.NEWSEQUENTIALID()
decididamente no es completamente al azar, pero ese es su propósito : generar UUID que funcionen bien (al igual que los UUID pueden, al menos) como claves de índice.Respuestas:
Wikipedia tiene algunos detalles:
http://en.wikipedia.org/wiki/Universally_unique_identifier
http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates
Pero la probabilidad solo se mantiene si los bits son perfectamente aleatorios. Sin embargo, el RFC http://tools.ietf.org/html/rfc4122#page-14 vinculado en la otra respuesta define esto para la versión 4:
Esto permite prácticamente cualquier cosa, desde el generador aleatorio xkcd http://xkcd.com/221/ hasta un dispositivo de hardware que utiliza ruido cuántico. Las consideraciones de seguridad en el RFC:
Leí esto como: Estás solo. Usted es responsable de su generador aleatorio dentro de su propia aplicación, pero esto y cualquier otra cosa se basa en la confianza. Si no confía en su propia capacidad para comprender y utilizar correctamente el generador aleatorio de su elección, entonces es una buena idea verificar las colisiones. Si no confía en el programador de los otros procesos, compruebe si hay colisiones o use una versión de UUID diferente.
fuente
Sin duda, debe detectar si se produce una colisión, y su aplicación debería lanzar una excepción si sucede. Por ejemplo, si el UUID se usa como clave principal en la base de datos, la base de datos debería arrojar un error al insertar una identificación en colisión.
Sin embargo, creo que escribir código para generar un nuevo UUID en el caso de una colisión y volver a intentarlo es una pérdida de tiempo. La posibilidad de que ocurra una colisión es tan pequeña que lanzar una excepción sería una forma perfectamente razonable de tratarla.
Recuerde, no solo es una pérdida de tiempo escribir el código, sino que también lo hace más complejo, lo que dificulta la lectura de la siguiente persona, casi sin ganancia.
fuente
Esta es una muy buena pregunta. No creo que se haya considerado adecuadamente en la prisa por usar UUID en todas partes. No he encontrado ninguna investigación sólida.
Una sugerencia: pise con mucho cuidado aquí y conozca bien su criptografía. Si usa un UUID de 128 bits, el 'efecto de cumpleaños' nos dice que es probable que se produzca una colisión después de haber generado aproximadamente 2 ^ 64 claves, siempre que tenga 128 bits de entropía en cada clave .
En realidad, es bastante difícil garantizar que este sea el caso. La verdadera aleatoriedad puede generarse a partir de (a) la desintegración radiactiva (b) el ruido de fondo aleatorio de la radio, a menudo contaminado a menos que tenga cuidado (c) ruido electrónico elegido adecuadamente, por ejemplo, tomado de un diodo Zener de polarización inversa. (He jugado con el último, y funciona de maravilla, por cierto).
No confiaría en pronunciamientos como "No he visto esto en un año de uso", a menos que el usuario haya generado algo que se acerque a las teclas 2 ^ 64 (es decir, aproximadamente 10 ^ 19), y las haya verificado entre sí, un ejercicio no trivial
El problema es este. Digamos que tiene solo 100 bits de entropía, cuando compara sus claves con todas las otras claves que todos los demás generan en un espacio de claves común. Comenzará a ver colisiones en aproximadamente 2 ^ 50 es decir. Cerca de 10 ^ 15 teclas. Sus posibilidades de ver una colisión si ha llenado su base de datos con solo 1000 mil millones de claves siguen siendo insignificantes. Y si no verifica, más tarde obtendrá errores inesperados que se arrastran en su base de datos del tamaño de una fila peta. Esto podría morder con fuerza.
El hecho mismo de que existen múltiples enfoques para generar tales UUID debería causar un espasmo momentáneo de preocupación. Cuando se da cuenta de que pocos generadores usan procesos 'verdaderamente aleatorios' con suficiente entropía para un UUID tipo 4, debe preocuparse en exceso a menos que haya examinado cuidadosamente el contenido de entropía del generador. (La mayoría de las personas no harán esto, ni siquiera sabrán cómo hacerlo; puede comenzar con la suite DieHarder). NO confunda la generación de números pseudoaleatorios con la verdadera generación de números aleatorios.
Es crítico que te des cuenta de que la entropía que ingresas es la entropía que tienes, y simplemente perturbar la clave aplicando una función criptográfica no altera la entropía. Puede no ser intuitivamente obvio que si todo mi espacio comprende los dígitos 0 y 1, el contenido de entropía es el mismo que el de las siguientes dos cadenas, siempre que sean las únicas dos opciones: "Esta es una cadena realmente muy compleja 293290729382832 * ! @@ # & ^% $$) ,. m} "y" Y AHORA POR ALGO COMPLETAMENTE DIFERENTE ". Todavía hay solo dos opciones.
La aleatoriedad es difícil de entender, y simplemente creer que "los expertos lo han mirado, por lo tanto está bien" puede no ser suficiente. Los criptógrafos expertos (y hay pocos de estos que son realmente competentes) son los primeros en admitir que a menudo se equivocan. Confiamos en heartbleed, DigiNotar, etc.
Creo que Paul Tomblin está ejerciendo la precaución adecuada. Mi 2c.
fuente
El problema que tiene es que si usa un "generador de números aleatorios" y no sabe cuán aleatorio es ese generador, entonces la probabilidad de colisión es realmente desconocida. Si los generadores de números aleatorios están correlacionados de alguna manera, la probabilidad de colisión puede aumentar dramáticamente, posiblemente muchos, muchos órdenes o magnitud.
Incluso si tiene una probabilidad muy pequeña de colisión, tiene un problema fundamental: la probabilidad NO es 0. Esto significa que eventualmente ocurrirá una colisión, simplemente no ocurrirá con mucha frecuencia.
Cuanto más frecuentemente genere y use los UUID, más pronto se verá esa colisión. (generar 1 por año significa un tiempo de espera más largo que generar un millón por segundo, todas las demás cosas son iguales).
Si esa probabilidad es finita, desconocida, y usa muchos UUID, entonces debe considerar las consecuencias de una colisión. Si no es aceptable lanzar una excepción y cerrar una aplicación comercial, ¡no lo haga! (Ejemplos en la parte superior de mi cabeza: "Está bien apagar el servidor web en medio de la actualización de un registro de la biblioteca ... no sucederá con frecuencia" y "Está bien cerrar el sistema de nómina en medio de haciendo la carrera de pago ". Estas decisiones pueden ser movimientos que limitan la carrera.)
Sin embargo, es posible que tenga un caso peor, de nuevo dependiendo de su aplicación. Si prueba la presencia de un UUID (es decir, realiza una búsqueda) y luego hace uno nuevo si todavía no está allí, lo cual es algo bastante común, entonces puede encontrar que está vinculando registros o estableciendo relaciones , cuando de hecho está conectando 2 cosas a través de un UUID que no debe conectarse. Esto es algo en lo que arrojar una excepción no resolverá nada y tendrás un desastre indetectable creado en alguna parte. Este es el tipo de cosa que conduce a la fuga de información y puede ser muy vergonzoso. (Ej: ¡Ingrese a su banco y descubra que puede ver el saldo de la cuenta de otra persona! ¡Malo!)
Resumen: debe considerar la forma en que se usan sus UUID y las consecuencias de una colisión. Esto determina si debe tener cuidado para detectar y evitar colisiones, realizar alguna acción simple en caso de colisión o no hacer nada. Es probable que una solución simple, única y adecuada para todos sea inapropiada en algunas circunstancias.
fuente
Hay dos problemas involucrados:
Calidad de los generadores de números aleatorios que se utilizan.
Cantidad de UUID que se pueden generar.
Un UUID "aleatorio" tiene 122 bits aleatorios. Suponiendo una aleatoriedad perfecta, puede esperar la primera colisión en alrededor de 2 ^ 61 UUID generados (esa es la raíz cuadrada de 2 ^ 122). Si todos en este mundo generaran un UUID por segundo, eso es 10,000,000,000 * 365 * 24 * 60 * 60 = 315360000000000000 UUID por año, que es bastante cercano a 2 ^ 58. Es decir, después de unos años obtendrías las primeras colisiones. A menos que su aplicación se acerque a esos números, puede estar bastante seguro de que no tendrá una colisión si su generador aleatorio es de buena calidad.
Hablando sobre el generador de números aleatorios: si usa los generadores de bibliotecas C estándar (directa, indirectamente o generadores similares), probablemente los siembra con el tiempo, usted es astuto. Estos no pueden aprovechar suficiente entropía para evitar colisiones. Sin embargo, si está en Linux, solo lea 16 bytes de datos de
/dev/urandom
: Esto se basa en un grupo de entropía que es agitado por el núcleo, que tiene acceso a algunos eventos aleatorios reales. A menos que normalmente genere UUID realmente, muy temprano en la secuencia de arranque,/dev/urandom
debería comportarse como una verdadera fuente aleatoria.fuente
Lo probé una vez usando un programa bastante simple (fuerza bruta) que generó 10 millones de UUID-s y no he experimentado una colisión.
El UUID RFC dice que el UUID no es solo un grupo de números (pseudo) aleatorios.
fuente