¿Qué es un generador de números aleatorios?

Un generador de números aleatorios (RNG) es un sistema que produce números aleatorios o pseudoaleatorios. Que el siguiente número pueda predecirse en la práctica depende del tipo de generador. Algunos generadores se basan en un proceso físico, otros calculan sus números mediante un algoritmo, y ciertos algoritmos están diseñados para que nadie que haya visto sus resultados pueda predecir qué vendrá después. Parecer aleatorio y ser impredecible son propiedades distintas, y la mayor parte de este artículo explica esa diferencia.

Generadores de números aleatorios por hardware

Un generador de números aleatorios por hardware (HRNG), también conocido como generador de números aleatorios verdaderos (TRNG), obtiene sus números a partir de un proceso físico. Los más antiguos funcionan a la vista de todos: una moneda al aire, un dado o una ruleta. Las leyes de la mecánica describen su comportamiento por completo, pero una ruleta bien construida sigue siendo impredecible en la práctica, ya que variaciones diminutas al iniciar cada giro generan resultados totalmente distintos.

En cambio, los generadores físicos modernos miden fenómenos microscópicos: ruido de disparo y ruido térmico en circuitos electrónicos, ruido atmosférico o efectos cuánticos. Son excelentes fuentes de entropía —imprevisibilidad cuantificable—, pero una fuente física no es perfecta por naturaleza: puede tener sesgo, sufrir desviaciones con el tiempo o fallar por completo. Por eso su calidad debe evaluarse y monitorizarse constantemente, y sus valores procesarse adicionalmente cuando sea necesario, tal como describen normas como NIST SP 800-90B. Las fuentes por hardware se utilizan donde las garantías son críticas, sobre todo en criptografía, donde aportan el punto de partida impredecible para generar las claves de protocolos como Transport Layer Security (TLS).

Generadores de números pseudoaleatorios

La alternativa a un dispositivo físico es un algoritmo. Un generador de números pseudoaleatorios (PRNG) produce una secuencia que parece aleatoria, pero que está completamente determinada por un valor inicial llamado semilla (seed). Si introduces la misma semilla en el mismo algoritmo, obtendrás exactamente la misma secuencia cada vez. Esto supone una desventaja cuando el resultado debe ser impredecible y la semilla o el estado interno pueden adivinarse o reconstruirse; pero es una gran ventaja cuando el resultado debe ser reproducible, ya que así una simulación o una prueba puede repetirse exactamente igual. Los PRNG también son rápidos, económicos y fáciles de implementar, razón por la cual la mayoría del software recurre a ellos. Entre los algoritmos más conocidos destacan el generador lineal congruencial (LCG), los generadores xorshift y el Mersenne Twister.

Mersenne Twister

El Mersenne Twister, presentado en 1997 por Makoto Matsumoto y Takuji Nishimura, es uno de los generadores pseudoaleatorios más extendidos y la opción predeterminada en numerosos lenguajes de programación. Su nombre proviene de su periodo —la longitud de la secuencia antes de repetirse—, que en la variante estándar, MT19937, es el primo de Mersenne 219937 − 1. Supera la mayoría de las pruebas estadísticas de aleatoriedad y resulta idóneo para simulaciones. Sin embargo, no fue diseñado para guardar secretos: a partir de 624 valores consecutivos de 32 bits, cualquiera puede reconstruir su estado interno y predecir todos los números siguientes, por lo que nunca debe emplearse para generar claves, contraseñas ni nada que deba ser impredecible.

Generadores criptográficamente seguros y entropía

Muchas aplicaciones necesitan ambas cualidades a la vez: la rapidez de un algoritmo y la imprevisibilidad de una fuente física. La solución es un generador de números pseudoaleatorios criptográficamente seguro (CSPRNG). Sigue siendo un tipo de PRNG, pero diseñado de tal forma que conocer una parte de sus resultados no ofrece ninguna manera viable de predecir los siguientes, y se inicializa (y reinicializa periódicamente) a partir de una fuente de entropía real. Una semilla procedente de un origen físico no hace seguro a un PRNG común; el algoritmo debe estar concebido específicamente para ello. Una fuente física, como el ruido térmico o los intervalos entre eventos del hardware, aporta una pequeña cantidad de aleatoriedad auténtica, y el CSPRNG obtiene de ella una larga secuencia de valores a una velocidad mucho mayor. Esta combinación es la que proporcionan los sistemas operativos a los programas y lo que suele entenderse hoy en día por «generador de números aleatorios». Con ella se crean claves de cifrado, tokens de sesión y contraseñas.

Números aleatorios en el navegador

JavaScript ofrece a las páginas web dos formas integradas de obtener valores aleatorios, pertenecientes a categorías muy distintas. Math.random() es un PRNG convencional: la especificación del lenguaje delega el algoritmo en cada navegador y no garantiza seguridad alguna, lo cual basta para una animación visual, pero resulta inadecuado para un sorteo que alguien pudiera impugnar. La alternativa es la Web Crypto API. Su método crypto.getRandomValues() genera valores aleatorios criptográficamente seguros, producidos por un CSPRNG que se nutre de la entropía del sistema operativo.

Nuestro generador de números aleatorios utiliza la Web Crypto API en cada generación, y los números se generan en tu navegador y no en un servidor remoto. Esta misma fuente alimenta las demás herramientas de este sitio, ya sea para lanzar dados, lanzar una moneda o generar una contraseña.

De bits aleatorios a un número en tu rango

Un generador criptográficamente seguro es solo la mitad de un sorteo justo. El generador entrega bits sin procesar, y el programa debe convertirlos en un número dentro del rango elegido; y aquí es donde algunos números pueden acabar con más probabilidades que otros. Imagina que la fuente genera valores del 0 al 9 con idéntica probabilidad y necesitas un número del 0 al 5. Calcular el resto al dividir entre 6 parece intuitivo, pero entonces los números 0, 1, 2 y 3 pueden salir de dos formas distintas, mientras que el 4 y el 5 solo de una; así, cada número del 0 al 3 tiene un 20% de probabilidad, y el 4 y el 5 solo un 10% cada uno. Una forma de eliminar este sesgo consiste en descartar los valores sobrantes y volver a generar; los materiales sobre números aleatorios explican este procedimiento con detalle.

Hay otros dos aspectos que suelen llamar la atención. Que salgan repeticiones es completamente normal: cuando se extrae al azar un número entero del 1 al 10 de manera independiente y con idéntica probabilidad, el número recién salido tiene exactamente la misma probabilidad de 1 entre 10 de volver a salir que cualquier otro. Un sorteo sin repeticiones es simplemente un tipo de sorteo distinto, no uno más aleatorio. Además, un generador imparcial por sí solo no garantiza que todo el proceso sea justo: la lista de participantes y el número de intentos cuentan tanto como el algoritmo, tal como explica nuestro artículo sobre cómo elegir una ganadora del concurso al azar.