medios - generar numeros aleatorios entre 0 y 1 en c#
¿Cómo puedo generar números verdaderamente(no pseudo) aleatorios con C#? (12)
Sé que la clase Random puede generar números pseudoaleatorios, pero ¿hay alguna manera de generar números realmente aleatorios?
Como bromeó John von Neumann, "Cualquiera que considere métodos aritméticos para producir dígitos aleatorios está, por supuesto, en estado de pecado".
Eche un vistazo usando un algoritmo como Yarrow o Fortuna con acumulación de entropía. El punto de estos algoritmos es que hacen un seguimiento de la entropía como una medida del contenido de información teórica disponible para predecir números futuros al conocer los números anteriores y los algoritmos utilizados para producirlos; y usan técnicas criptográficas para doblar nuevas fuentes de entropía en el generador de números.
Necesitará una fuente externa de datos aleatorios (por ejemplo , fuente de números aleatorios ), ya sea tiempo de pulsaciones de tecla, movimiento del mouse o tiempos de acceso al disco duro, temperatura de la CPU o datos de la cámara web o de acciones, o lo que sea - pero en cualquier caso, sigues mezclando esta información en los pools de entropía, por lo que incluso si los datos verdaderamente aleatorios son lentos o de baja calidad, es suficiente para que las cosas continúen de manera impredecible.
El hilo es viejo y respondió, pero pensé que seguiría de todos modos. Es para completar y la gente debería saber algunas cosas sobre Random en c #.
En cuanto a lo verdaderamente aleatorio, lo mejor que puedes esperar es usar un "generador pseudo aleatorio seguro" como salsa20 o RC4 (más o menos, a veces). Pasan un aluvión de pruebas donde los adversarios "eficientes" intentan distinguirlos del azar. Esto tiene ciertos costos y probablemente sea innecesario para la mayoría de los usos.
La clase aleatoria en c # es bastante buena la mayor parte del tiempo, tiene una distribución estática que parece aleatoria. Sin embargo, la semilla predeterminada para random () es la hora del sistema. Entonces, si tomas muchos randoms al mismo tiempo, se toman con la misma semilla y serán los mismos ("aleatorio" es completamente determinista, no dejes que te engañe). Las semillas similares en el tiempo del sistema también pueden producir números similares debido a las deficiencias de las clases aleatorias. La forma de lidiar con esto es establecer sus propias semillas, como
Random random = new Random((int)DateTime.Now.Ticks & (0x0000FFFF + x));
donde x es un valor que incrementa si ha creado un bucle para obtener un grupo de números aleatorios, por ejemplo.
También con c # extensiones aleatorias a su nueva variable como NextDouble () puede ser útil en la manipulación de los números aleatorios, en este caso crow-baring en intervalo (0,1) para convertirse unif (0,1), lo que sucede es una distribución que puede conectarse a fórmulas de estadísticas para crear todas las distribuciones en estadísticas.
Estaba debatiendo la creación de un generador de números aleatorios basado en Twitter o en uno de los otros sitios de redes sociales. Básicamente use la API para extraer publicaciones recientes y luego use eso para generar un generador de números pseudoaleatorios de alta calidad. Probablemente no sea más efectivo que aleatorizar el temporizador, pero parecía divertido. Además, parece ser el mejor uso para la mayoría de las cosas que las personas publican en Twitter.
Este código te devolverá un número aleatorio entre min
y max
:
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public int RandomNumber(int min, int max)
{
lock (syncLock)
{ // synchronize
return random.Next(min, max);
}
}
Uso:
int randomNumber = RandomNumber(0, 10); // a random number between 1 and 10
La respuesta aquí tiene dos lados principales. Hay algunas sutilezas bastante importantes a las que debes prestar la debida atención ...
The Easy Way (por simplicidad y practicidad)
El RNGCryptoServiceProvider
, que es parte de Crypto API en BCL, debería hacer el trabajo por usted. Todavía es técnicamente un número pseudoaleatorio generado, pero la calidad de "aleatoriedad" es mucho más alta, adecuada para fines criptográficos, como su nombre podría sugerir.
También hay disponibles otras API criográficas con generadores pseudoaleatorios de alta calidad. Algoritmos como el tornado Mersenne son bastante populares.
Comparando esto con la clase Random
en el BCL, es significativamente mejor. Si trazas los números generados por Random
en un gráfico, por ejemplo, deberías ser capaz de reconocer patrones, lo cual es una fuerte señal de debilidad. Esto se debe en gran parte al hecho de que el algoritmo simplemente usa una tabla de búsqueda de tamaño fijo.
The Hard Way (para la aleatoriedad teórica de alta calidad)
Para generar números verdaderamente aleatorios, debe hacer uso de algún fenómeno natural, como la descomposición nuclear, las fluctuaciones de temperatura microscópicas (la temperatura de la CPU es una fuente comparativamente conveniente), por nombrar algunos. Sin embargo, esto es mucho más difícil y requiere hardware adicional, por supuesto. Sospecho que la solución práctica ( RNGCryptoServiceProvider
o RNGCryptoServiceProvider
) debería hacer el trabajo perfectamente para usted.
Ahora, tenga en cuenta que si realmente necesita números verdaderamente aleatorios , podría usar un servicio como Random.org , que genera números con una aleatoriedad / entropía muy alta (basada en el ruido atmosférico ). Los datos están disponibles de forma gratuita para su descarga. Sin embargo, esto puede ser innecesariamente complicado para su situación, aunque ciertamente le brinda datos adecuados para el estudio científico y demás.
La elección es suya al final, pero al menos ahora debería poder tomar una decisión informativa, teniendo en cuenta los distintos tipos y niveles de RNG.
Los verdaderos números aleatorios solo pueden generarse si hay un dispositivo de entrada física verdaderamente aleatorio que proporciona la semilla para la función aleatoria.
Si la existencia de algo físico y verdaderamente aleatorio existe todavía es debatido (y probablemente lo será durante mucho tiempo) por la comunidad científica.
Los generadores de números Psuedo-aleatorios son la mejor opción y los mejores son muy difíciles de predecir.
No existe un "verdadero" azar en las computadoras, todo se basa en otra cosa. Para algunas formas (factibles) de generar datos pseudoaleatorios, pruebe algo como un conjunto de temp. HD, temperatura de CPU, uso de red (paquetes / segundo) y posiblemente accesos / segundo al servidor web.
No hay forma de generar números verdaderamente aleatorios con una computadora. La verdadera aleatoriedad requiere una fuente externa que monitorea algún fenómeno natural.
Dicho esto, si no tiene acceso a esa fuente de números verdaderamente aleatorios, podría usar un proceso de "pobre hombre" como este:
- Crear una matriz larga (¿10000 o más elementos?) De números
- Llene la matriz con los números aleatorios con fecha actual de la manera estándar
- Cuando se requiere un número aleatorio, genere un índice aleatorio en la matriz y devuelva el número que figura en esa posición
- Cree un número aleatorio nuevo, actual y sembrado en el índice de matriz para reemplazar el número utilizado
Este proceso de dos pasos debería mejorar un poco la aleatoriedad de sus resultados sin necesidad de aportes externos.
Aquí hay una biblioteca de muestra que implementa el algoritmo descrito anteriormente en C ++: http://www.boost.org/doc/libs/1_39_0/libs/random/random-generators.html
Siempre me ha gustado esta idea, para el look retro de los 60:
Solo para aclarar que todo el mundo dice que no hay True RNG disponible en C # o en su computadora está equivocado. Un procesador multi-core es intrínsecamente un RNG verdadero. Muy simplemente, aprovechando el giro del procesador, puede generar bools que no tienen un patrón discernible. A partir de ahí, puede generar el rango numérico que desee utilizando los bools como bits y construyendo el número al sumar los bits.
Sí, esto es más lento que una solución puramente matemática, pero una solución puramente matemática siempre tendrá un patrón.
public static bool GenerateBoolean()
{
var gen1 = 0;
var gen2 = 0;
Task.Run(() =>
{
while (gen1 < 1 || gen2 < 1)
Interlocked.Increment(ref gen1);
});
while (gen1 < 1 || gen2 < 1)
Interlocked.Increment(ref gen2);
return (gen1 + gen2) % 2 == 0;
}
respuesta corta: no es directamente posible generar NÚMEROS VERDADERAMENTE ALEATORIOS usando solo C # (es decir, usando solo una construcción puramente matemática).
respuesta larga (er): solo mediante el empleo de un dispositivo externo capaz de generar "aleatoriedad", como un generador de ruido blanco o similar , y la captura de la salida de ese dispositivo como una semilla para un generador de números pseudoaleatorios (PRG). Esa parte se puede lograr usando C #.