Hubo un artículo realmente bueno que leí recientemente sobre diferentes tipos de PRNG y cómo les va en términos de varias pruebas de aleatoriedad diferentes. Desafortunadamente, parece que no puedo encontrarlo ahora. La esencia de esto, sin embargo, era que los generadores de números aleatorios predeterminados en casi todos los lenguajes de programación populares son bastante ingenuos y tienen sesgos bastante significativos.
Otra respuesta ya menciona que no hay ningún PRNG, sin importar cuán sofisticado sea el algoritmo, es lo suficientemente bueno para aplicaciones criptográficas. Esto es verdad. Como mencionas que esto se usará para "seleccionar un ticket ganador", ignorémoslo por el momento.
El algoritmo Knuth utilizado por la clase .NET System.Random
está optimizado principalmente para la distribución de velocidad, no aleatoria. Es "lo suficientemente aleatorio" para muchos propósitos, de los cuales la mayoría de las aplicaciones nunca se alejan demasiado, pero en los campos de (a) juegos y (b) simulación estadística, la mayoría de la gente parece pensar que es una mala elección. Es mejor que los LCG que solían ser los predeterminados en las bibliotecas antiguas, pero aún así no desea utilizarlo para algo así como una lotería.
No te dejes engañar pensando que solo usas una fuente criptográfica. El problema con los RNG criptográficos es que llenan una secuencia de bytes, pero convertir esto en un único entero aleatorio entre x y y requiere que haga aritmética modular (o redondeo, el mismo resultado de cualquier manera). Y si su rango aleatorio no se divide perfectamente en cualquier potencia de 2 definida por la longitud del byte, entonces va a terminar con un sesgo en los números más bajos. Los datos generados tienen alta entropía, pero su resultado estará sesgado.
Como un simple ejemplo, digamos que obtienes un número aleatorio "perfecto" de 1 a 10 y ahora quieres convertirlo en un número aleatorio entre 1 y 7. ¿Cómo lo haces? Simplemente calculando result % 7
estará muy predispuesto hacia los números 1-3. Hay algunas maneras de reducir el sesgo al usar un RNG criptográfico, pero el punto que estoy tratando de plantear es que los RNG criptográficos están diseñados para aplicaciones criptográficas, y usar uno de esos para una simulación de Monte Carlo no suele ser la mejor idea.
Hasta donde yo sé, el PRNG "bueno" más popular actualmente, que se usa comúnmente en aplicaciones de juegos, es el Mersenne Twister. Hay un .NET implementation here. Este algoritmo pasa todos los Diehard Tests para distribución aleatoria; muestra casi ningún sesgo y es una buena opción cuando usa números aleatorios para aplicaciones probabilísticas y estadísticas.
La Biblioteca Científica GNU también tiene un número de RNG algorithms y, como era de esperar, el Mersenne Twister se encuentra en la parte superior de la lista.Sin embargo, vale la pena mirar algunas de las otras por curiosidad; RANLUX también puntúa bastante alto en la prueba de dietas IIRC.
Eric tiene razón con su comentario, por supuesto; toda esta información es en vano si no tiene requisitos técnicos específicos sobre "qué tan aleatorio" necesita que sean sus números aleatorios. Estoy usando una definición que sería aplicable a una aplicación de juego/juegos de azar de impacto relativamente bajo (es decir, no es un sitio de juego registrado importante con millones de visitantes por día; existen reglas más estrictas sobre la aleatoriedad para ellos).
Defina con claridad y precisión "lo más aleatorio posible". Para obtener una señal que es en realidad "lo más aleatoria posible", necesita una fuente de entropía, la semilla, que tiene más bits de entropía que el elemento aleatorio generado a partir de esa semilla. Entonces, si ya tiene una variedad de fuentes de datos para la semilla, y son de alta entropía, entonces ya está listo. Simplemente extraiga 24 bits de su fuente de entropía, y eso le da un número entre 0 y 16 millones que es ** lo más aleatorio posible dada su fuente de entropía **. –
Además, sería tremendamente útil si describiera para qué va a utilizar este número aleatorio. –
Re: su actualización: ahora ya no está en el ámbito únicamente de las matemáticas y la tecnología, sino en el ámbito de las regulaciones legales. La mayoría de las personas que leen esto no son abogados familiarizados con las leyes sobre qué características debe poseer un dispositivo que elige el ganador de una lotería. Recomendaría consultar con un abogado y un estadístico antes de dedicar más tiempo a buscar una solución técnica. Ciertamente, ninguna solución * simple * "pseudo aleatoria" será aceptable; uno puede calcular fácilmente cuál es el próximo número ganador de los anteriores con un PRNG. –