Esta pregunta no es realmente un problema para buscar una solución, es más una simple cuestión de curiosidad. La función uniqid de PHP tiene un indicador de más entropía, para hacer que la salida sea "más única". Esto me hizo preguntarme, ¿qué tan probable es que esta función produzca el mismo resultado más de una vez cuando more_entropy es verdadero, versus cuando no lo es? En otras palabras, ¿qué tan único es uniqid cuando more_entropy está habilitado, en comparación con cuando está deshabilitado? ¿Hay algún inconveniente en tener more_entropy habilitado todo el tiempo?
76
uniqid
conmore_entropy
set da solo unos 92 bits de entropía (23 hexbits). Para entender por qué eso no es bueno para la singularidad, consulte El problema del cumpleaños ...more_entropy
tiene aproximadamente 30 bits de entropía (nueve dígitos decimales), la parte de microsegundos es aproximadamente 20 (seis dígitos decimales), ¿de dónde viene el resto? Debería elegir el segundo de un rango de 100.000 años para obtener 42 bits de entropía.Respuestas:
Actualización, marzo de 2014:
En primer lugar, es importante tener en cuenta que
uniqid
es un nombre poco apropiado, ya que no garantiza una identificación única.Según la documentación de PHP :
Y
Establecer more-entropy en true genera un valor más único, sin embargo, el tiempo de ejecución es más largo (aunque en un grado mínimo), según los documentos:
Tenga en cuenta la línea
increases the likelihood that the result will be unique
y no eso garantizará la singularidad.Puede esforzarse 'sin cesar' por la singularidad, hasta cierto punto, y mejorar utilizando cualquier número de rutinas de cifrado, agregando sales y cosas por el estilo, depende del propósito.
Recomiendo mirar los comentarios sobre el tema principal de PHP, en particular:
http://www.php.net/manual/en/function.uniqid.php#96898
http://www.php.net/manual/en/function.uniqid.php#96549
http://www.php.net/manual/en/function.uniqid.php#95001
Lo que recomendaría es averiguar por qué necesita la singularidad, ¿es por seguridad (es decir, para agregar a una rutina de cifrado / codificación)? Además, ¿qué tan único debe ser? Finalmente, mire la consideración de velocidad. La idoneidad cambiará con las consideraciones subyacentes.
fuente
uniqid
(o sus derivados) para nada relacionado con la seguridad. PHP ofrece una gran cantidad de generadores aleatorios criptográficos de seguridad, tales como:openssl_random_pseudo_bytes
. Utilice la herramienta adecuada para el trabajo.do{} while(collision)
. Utilizo este enfoque al generar rutas para archivos cargados, por ejemplo.Las cosas solo son únicas si comprueba que aún no existen. No importa qué función use para generar una cadena 'aleatoria', o ID; si no verifica que no sea un duplicado, siempre existe la posibilidad ...;)
Si bien uniqid se basa en la hora actual, la nota de advertencia anterior aún se aplica; solo depende de dónde usará estos "ID únicos". La clave de todo esto es donde dice "más singular". Único es único es único. ¡Cómo puedes tener algo que es más o menos único, me confunde un poco!
Verificar lo anterior y combinar todas estas cosas le permitirá terminar con algo que se acerca a la singularidad, pero todo está relacionado con dónde se usarán las claves y el contexto. ¡Espero que ayude!
fuente
10^47
años solo para tener un 50% de probabilidad de una colisión ... Así que sí, con un límite superior lo suficientemente alto en el número aleatorio Y un RNG lo suficientemente bueno, puede simular la singularidad con solo aleatoriedad ...rand()
, tendrían> 90% de posibilidades de colisión en la primera iteración . Además, si necesita singularidad, incluso una probabilidad de colisión del 0,001% es demasiado.De las discusiones sobre la función en el sitio del manual de PHP:
En otras palabras, sin "more_entropy", la función es absolutamente horrible y nunca debería usarse, punto. Según la documentación, la bandera usará un "generador congruencial lineal combinado" para "agregar entropía". Bueno, ese es un RNG bastante débil. Así que omitiría esta función por completo y usaría algo basado en mt_rand con una buena semilla para cosas que no son relevantes para la seguridad, y SHA-256 para cosas que sí lo son.
fuente
Sin el indicador more_unique, devuelve la marca de tiempo de Unix con un contador de microsegundos, por lo tanto, si se realizan dos llamadas en el mismo microsegundo, devolverán la misma identificación 'única'.
De ahí que sea una cuestión de qué tan probable es eso. La respuesta es no mucho, pero no en un grado descontable. Si necesita una identificación única y la genera con frecuencia (o trabaja con datos generados en otros lugares), no cuente con que sea absolutamente única.
fuente
El bit relevante del código fuente es
if (more_entropy) { uniqid = strpprintf(0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg() * 10); } else { uniqid = strpprintf(0, "%s%08x%05x", prefix, sec, usec); }
Por lo tanto,
more_entropy
agrega nueve dígitos decimales algo aleatorios (php_combined_lcg()
devuelve un valor en(0,1)
); eso es 29.9 bits de entropía, como máximo (en realidad, probablemente menos, ya que LCG no es un generador de números pseudoaleatorios criptográficamente seguro).fuente