Pregunta

Sé que solo usando rand() Es predecible si sabes lo que estás haciendo y tienes acceso al servidor.

tengo un proyecto que es altamente depende de elegir un número aleatorio que sea lo más impredecible posible.Así que estoy buscando sugerencias, ya sea otras funciones integradas o funciones de usuario, que puedan generar una mejor número aleatorio.

Usé esto para hacer una pequeña prueba:

$i = 0;

while($i < 10000){
    $rand = rand(0, 100);

    if(!isset($array[$rand])){
        $array[$rand] = 1;
    } else {
        $array[$rand]++;
    }

    sort($array);
    $i++;
}

Encontré que los resultados están distribuidos uniformemente y hay un patrón impar en la cantidad de veces que se genera cada número.

¿Fue útil?

Solución

Sumar, multiplicar o truncar una fuente aleatoria deficiente dará un resultado aleatorio deficiente.Ver Introducción a la aleatoriedad y los números aleatorios para una explicación.

Tienes razón sobre la función PHP rand().Vea la segunda figura en Análisis estadístico para una ilustración sorprendente.(La primera figura es sorprendente, pero ha sido dibujada por Scott Adams, no trazada con rand()).

Una solución es utilizar un generador aleatorio verdadero como aleatorio.org.Otro, si estás en Linux/BSD/etc.es usar /dev/aleatorio.Si la aleatoriedad es de misión crítica, tendrás que usar un generador aleatorio de hardware.

Otros consejos

aleatorio.org tiene una API a la que puede acceder a través de HTTP.

Random.org es un verdadero servicio de números aleatorios que genera aleatoriedad a través del ruido atmosférico.

Yo desconfiaría de la impresión de aleatoriedad:Ha habido muchos experimentos en los que la gente elegiría la distribución menos aleatoria.Parece que la mente no es muy buena para producir o estimar la aleatoriedad.

Hay buenos artículos sobre aleatoriedad en Fourmilab, incluyendo otro verdadero generador aleatorio.Tal vez pueda obtener datos aleatorios de ambos sitios, de modo que si uno no funciona, aún tendrá el otro.

Fourmilab también proporciona un Programa de prueba para comprobar la aleatoriedad.Puede usarlo para verificar sus diversos programas myRand().

En cuanto a tu último programa, si generas 10000 valores, ¿por qué no eliges el valor final entre los 10 mil?Te limitas a un subconjunto.Además, no funcionará si su $min y $max son mayores que 10000.

De todos modos, la aleatoriedad que necesitas depende de tu aplicación.rand() estará bien para un juego en línea, pero no para criptografía (cualquier cosa que no se haya probado exhaustivamente con programas estadísticos no será adecuada para criptografía de todos modos).¡Sé tú el juez!

¿Variación en @KG, usando los milisegundos desde EPOCH como semilla para rand?

Otra forma de obtener números aleatorios, similar en concepto a obtener UUID

PHP versión 5.3 y superior

openssl_random_pseudo_bytes(...)

O puedes probar lo siguiente biblioteca usando RFC4122

un nuevo PHP7 hay una función que hace exactamente lo que necesitabas:genera enteros pseudoaleatorios criptográficamente seguros.

int random_int ( int $min , int $max )

Genera enteros criptográficos aleatorios que son adecuados para su uso donde los resultados imparciales son críticos (es decir,barajar una baraja de póquer).

Para obtener una explicación más detallada sobre PRNG y CSPRNG (y su diferencia), así como por qué su enfoque original es en realidad una mala idea, lea mi otra respuesta muy similar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top