Generador de números aleatorios: ¿Cómo generan las computadoras números aleatorios?

La gente ha estado usando números aleatorios durante milenios, por lo que el concepto no es nuevo. Desde la lotería en la antigua Babilonia hasta las mesas de ruleta en Montecarlo y los juegos de dados en Las Vegas, el objetivo es dejar el resultado final al azar.

Pero dejando de lado el juego, la aleatoriedad tiene muchos usos en ciencia, estadística, criptografía y más. Sin embargo, el uso de dados, monedas o medios similares como dispositivo aleatorio tiene sus limitaciones.

Debido a la naturaleza mecánica de estas técnicas, generar grandes cantidades de números aleatorios requiere una gran cantidad de tiempo y trabajo. Gracias al ingenio humano, tenemos herramientas y métodos más poderosos a nuestra disposición.

Métodos para generar números aleatorios

Números aleatorios verdaderos

robot electrónico de forma libre mirando a su alrededor

Consideremos dos métodos principales utilizados para generar números aleatorios. El primer método esbasado en un proceso físico, y cosecha la fuente de aleatoriedad de algún fenómeno físico que se espera que sea aleatorio .

Tal fenómeno ocurre fuera de la computadora. Se mide y ajusta para posibles sesgos debidos al proceso de medición. Los ejemplos incluyen la desintegración radiactiva, el efecto fotoeléctrico, la radiación cósmica de fondo, el ruido atmosférico (que usaremos en este artículo) y más.

Por lo tanto, se dice que los números aleatorios generados en base a dicha aleatoriedad son números aleatorios " verdaderos ".

Técnicamente, la parte de hardware consiste en un dispositivo que convierte la energía de una forma a otra (por ejemplo, radiación en una señal eléctrica), un amplificador y un convertidor de analógico a digital para convertir la salida en un número digital.

¿Qué son los números pseudoaleatorios?

Código de ataque binario de hacker.  Hecho con Canon 5d Mark III y lente analógica vintage, Leica APO Macro Elmarit-R 2.8 100 mm (año: 1993)

Como alternativa a los números aleatorios "verdaderos", el segundo método para generar números aleatorios implica algoritmos computacionales que pueden producir resultados aparentemente aleatorios.

¿Por qué aparentemente al azar? Porque los resultados finales obtenidos están de hecho completamente determinados por un valor inicial también conocido como valor semilla o clave . Por lo tanto, si conociera el valor de la clave y cómo funciona el algoritmo, podría reproducir estos resultados aparentemente aleatorios.

Los generadores de números aleatorios de este tipo se denominan frecuentemente generadores de números pseudoaleatorios y, como resultado, generan números pseudoaleatorios.

Aunque este tipo de generador normalmente no recopila datos de fuentes de aleatoriedad natural, dicha recopilación de claves puede ser posible cuando sea necesario.

Comparemos algunos aspectos de los verdaderos generadores de números aleatorios o TRNG y los generadores de números pseudoaleatorios o PRNG .

Los PRNG son más rápidos que los TRNG. Debido a su naturaleza determinista, son útiles cuando necesita reproducir una secuencia de eventos aleatorios. Esto ayuda mucho en las pruebas de código, por ejemplo.

Por otro lado, los TRNG no son periódicos y funcionan mejor en roles sensibles a la seguridad, como el cifrado.

Un período es el número de iteraciones por las que pasa un PRNG antes de que comience a repetirse. Por lo tanto, en igualdad de condiciones, un PRNG con un período más largo requeriría más recursos informáticos para predecir y descifrar.

Algoritmo de ejemplo para un generador de números pseudoaleatorios

Una computadora ejecuta código que se basa en un conjunto de reglas a seguir. Para los PRNG en general, esas reglas giran en torno a lo siguiente:

  1. Acepte algún número de entrada inicial, que es una semilla o clave.
  2. Aplique esa semilla en una secuencia de operaciones matemáticas para generar el resultado. Ese resultado es el número aleatorio.
  3. Utilice ese número aleatorio resultante como semilla para la siguiente iteración.
  4. Repita el proceso para emular la aleatoriedad.

Ahora veamos un ejemplo.

El generador congruencial lineal

Este generador produce una serie de números pseudoaleatorios. Dada una semilla inicial X 0 y parámetros enteros a como multiplicador, b como incremento ym como módulo, el generador se define por la relación lineal: X n ≡ (aX n-1 + b) mod m . O usando una sintaxis más amigable con la programación: X n = (a * X n-1 + b)% m .

Cada uno de estos miembros debe cumplir las siguientes condiciones:

  • m> 0 (el módulo es positivo),
  • 0 <a <m (el multiplicador es positivo pero menor que el módulo),
  • 0b <m (elel incremento es no negativo pero menor que el módulo), y
  • 0X 0 <m (la semilla no es negativa pero menor que el módulo).

Creemos una función de JavaScript que tome los valores iniciales como argumentos y devuelva una matriz de números aleatorios de una longitud determinada:

 // x0=seed; a=multiplier; b=increment; m=modulus; n=desired array length; const linearRandomGenerator = (x0, a, b, m, n) => { const results = [] for (let i = 0; i < n; i++) { x0 = (a * x0 + b) % m results.push(x0) } return results } 

El generador de congruencia lineal es uno de los algoritmos PRNG más antiguos y conocidos.

En cuanto a los algoritmos de generación de números aleatorios que son ejecutables por computadoras, se remontan a las décadas de 1940 y 1950 (el método del cuadrado medio y el generador de Lehmer, por ejemplo) y continúan escribiéndose en la actualidad (Xoroshiro128 +, Squares RNG, y más) .

Un ejemplo de generador de números aleatorios

Cuando decidí escribir este artículo sobre cómo incrustar un generador de números aleatorios en una página web, tuve que tomar una decisión.

Podría haber usado la Math.random()función de JavaScript como base y generar resultados en números pseudoaleatorios como lo hice en artículos anteriores (consulte Tabla de multiplicación: codifique su propia tabla de tiempos).

Pero este artículo en sí trata sobre la generación de números aleatorios. Así que decidí aprender a recopilar datos "verdaderos" basados ​​en la aleatoriedad y compartir mi descubrimiento con ustedes.

Así que a continuación está el "verdadero" generador de números aleatorios. Establezca los parámetros y presione Generar.

Verdadero generador de números aleatorios Binario decimal Hexadecimal Generar resultado:

The code fetches data from one of the APIs, courtesy of Random.org. This online resource has a plethora of useful, customizable tools and comes with excellent documentation to go with it.

The randomness comes from atmospheric noise. I was able to use asynchronous functions. That is a huge benefit going forward. The core function looks like this:

 // Generates a random number within user indicated interval const getRandom = async (min, max, base) => { const response = await  fetch("//www.random.org/integers/?num=1&min="+min+" &max="+max+"&col=1&base="+base+"&format=plain&rnd=new") return response.text() }

The parameters it takes allow a user to customize random number output. For example, min and max allow you to set lower and upper limits on generated output. And base determines if the output is printed as binary, decimal or hexadecimal.

Again, I chose this configuration but there are many more available at the source.

Cuando hace clic en el botón Generar, handleGenerate()se llama a la función. A su vez, invoca la getRandom()función asincrónica, administra el manejo de errores y genera resultados:

 // Output handling const handleGenerate = () => { handleActive(generateButton) const base = binary.checked ? 2 : decimal.checked ? 10 : 16 if (!minimum.value || !maximum.value) { prompter.style.color = 'red' prompter.textContent = "Enter Min & Max values" } else { getRandom(minimum.value, maximum.value, base).then((data) => { resultValue.textContent = data prompter.textContent = "" }).catch((error) => { resultValue.textContent = 'ERROR' prompter.textContent = 'Connection error. Unable to generate'; }) handleRestart() } } 

El resto del código trata de la estructura, apariencia y estilo de HTML.

El código está listo para ser incrustado y utilizado dentro de esta página web. Lo separé en partes componentes y le proporcioné comentarios detallados. Se puede modificar fácilmente. También puede modificar la funcionalidad y los estilos según lo requieran sus necesidades.

Este es el enlace al repositorio de GitHub del código completo: //github.com/sandroarobeli/random-generator