Generadores Aleatorios: Cómo Funcionan y Cuándo Usarlos

· 13 min de lectura

Los generadores aleatorios están en todas partes. Cada vez que mezclas una lista de reproducción, generas una contraseña, ejecutas una simulación o juegas un videojuego, un generador de números aleatorios está trabajando detrás de escena. Pero, ¿alguna vez te has preguntado cómo las computadoras — máquinas deterministas que siguen instrucciones exactas — producen aleatoriedad? La respuesta es más fascinante (y más matizada) de lo que podrías esperar.

Esta guía explora la ciencia y la ingeniería detrás de los generadores aleatorios. Cubriremos la diferencia entre números verdaderamente aleatorios y pseudo-aleatorios, cómo funcionan los algoritmos populares, cuándo necesitas aleatoriedad de grado criptográfico y aplicaciones prácticas que afectan tu vida diaria. Ya seas un desarrollador eligiendo la función aleatoria correcta, un estudiante aprendiendo sobre probabilidad, o simplemente curioso sobre cómo funcionan las cosas, esta guía te tiene cubierto.

¿Qué es la Aleatoriedad? Una Mirada Más Profunda

La aleatoriedad parece intuitiva — es imprevisibilidad, caos, la ausencia de patrón. Pero definir la aleatoriedad con precisión es sorprendentemente difícil, y los matemáticos lo han debatido durante siglos.

En el sentido más estricto, una secuencia es verdaderamente aleatoria si ningún algoritmo puede predecir el siguiente valor mejor que adivinando, incluso con conocimiento completo de todos los valores anteriores. Esto se llama aleatoriedad de Kolmogorov — una secuencia es aleatoria si no puede ser comprimida a una descripción más corta. Los dígitos de pi, por ejemplo, pasan todas las pruebas estadísticas de aleatoriedad, sin embargo son completamente deterministas (puedes calcular cualquier dígito con suficiente computación).

Para propósitos prácticos, nos importan tres propiedades de la aleatoriedad:

Diferentes aplicaciones requieren diferentes niveles de estas propiedades. Un juego de lanzamiento de dados necesita uniformidad e independencia, pero no necesariamente imprevisibilidad. Un generador de contraseñas necesita las tres. Entender qué tipo de aleatoriedad requiere tu aplicación es el primer paso para elegir el generador correcto.

Aleatorio Verdadero vs. Pseudo-Aleatorio: La División Fundamental

Todos los generadores aleatorios caen en dos categorías, y la distinción importa enormemente tanto para la corrección como para la seguridad.

Generadores de Números Verdaderamente Aleatorios (TRNGs)

Los generadores verdaderamente aleatorios derivan la aleatoriedad de fenómenos físicos que son fundamentalmente impredecibles:

La propiedad clave de los TRNGs es que su salida es no reproducible. Incluso con equipo y condiciones idénticas, obtendrás secuencias diferentes cada vez. Esto es esencial para aplicaciones criptográficas donde la reproducibilidad sería un fallo fatal.

Generadores de Números Pseudo-Aleatorios (PRNGs)

Los PRNGs son algoritmos — fórmulas matemáticas deterministas que producen secuencias de números que parecen aleatorios pero son completamente predecibles dado el estado inicial (llamado la semilla). Dale a un PRNG la misma semilla, y produce exactamente la misma secuencia cada vez.

Esto puede sonar como una debilidad, pero en realidad es una característica para muchas aplicaciones:

El desafío es diseñar PRNGs cuya salida sea estadísticamente indistinguible de la aleatoriedad verdadera — pasando todas las pruebas estadísticas conocidas de uniformidad, independencia y falta de patrón.

🎲 Prueba nuestros generadores

Generador de Números Aleatorios → Generador de Contraseñas →

Cómo Funcionan los Generadores de Números Pseudo-Aleatorios (PRNGs)

En su núcleo, los PRNGs mantienen un estado interno que transforman con cada llamada, produciendo una salida y actualizando el estado para la próxima vez. La calidad de un PRNG depende de qué tan bien su transformación evita patrones y correlaciones.

Generador Congruencial Lineal (LCG)

La familia de PRNGs más simple y antigua, los LCGs usan la fórmula:

estado = (a × estado + c) mod m
salida = estado

Donde a (multiplicador), c (incremento), y m (módulo) son constantes cuidadosamente elegidas. Por ejemplo, el generador clásico MINSTD usa a = 16807, c = 0, m = 2³¹ - 1. Los LCGs son increíblemente rápidos (una multiplicación y un módulo) pero tienen debilidades bien conocidas: los valores secuenciales muestran patrones cuando se grafican en dimensiones superiores, y los bits de orden bajo ciclan con períodos cortos. La mayoría de las aplicaciones modernas han superado los LCGs.

Mersenne Twister (MT19937)

El Mersenne Twister ha sido el PRNG predeterminado en muchos lenguajes y sistemas desde su introducción en 1997. Mantiene un estado de 624 enteros de 32 bits y tiene un período de 2¹⁹⁹³⁷ - 1 (un primo de Mersenne, de ahí el nombre). Ese período es astronómicamente largo — mucho más que el número de átomos en el universo observable.

El algoritmo funciona mediante:

  1. Inicializar 624 valores de estado desde una semilla
  2. Para cada número aleatorio, extraer y "templar" un valor de estado a través de desplazamientos de bits y operaciones XOR
  3. Regenerar periódicamente todo el arreglo de estado usando una transformación de torsión

Mersenne Twister pasa la mayoría de las pruebas estadísticas y es excelente para simulaciones, juegos y uso general. Sin embargo, no es criptográficamente seguro — observar 624 salidas permite reconstruir el estado interno completo y predecir todos los valores futuros.

Xoshiro256** y PRNGs Modernos

Los PRNGs más nuevos como xoshiro256** (usado en muchos lenguajes modernos) y PCG (Generador Congruencial Permutado) abordan las deficiencias de los generadores más antiguos. Ofrecen:

Math.random() de JavaScript

Cuando llamas a Math.random() en JavaScript, los motores modernos (V8, SpiderMonkey, JavaScriptCore) usan xorshift128+, un PRNG rápido con buenas propiedades estadísticas. Produce un número de punto flotante entre 0 (inclusivo) y 1 (exclusivo). Aunque perfectamente adecuado para juegos, mezclas y selección aleatoria, nunca debe usarse para propósitos sensibles a la seguridad.

// Número aleatorio básico entre min y max (inclusivo)
function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// Elemento aleatorio de un arreglo
function randomChoice(array) {
  return array[Math.floor(Math.random() * array.length)];
}

// Mezclar un arreglo (algoritmo Fisher-Yates)
function shuffle(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

Aleatoriedad Criptográfica: Cuando la Seguridad Importa

Para aplicaciones de seguridad — contraseñas, claves de cifrado, tokens de sesión, nonces — los PRNGs regulares son peligrosamente inadecuados. Un atacante que pueda predecir tus números aleatorios puede comprometer todo tu modelo de seguridad.

¿Qué Hace Diferente a un CSPRNG?

Un Generador de Números Pseudo-Aleatorios Criptográficamente Seguro (CSPRNG) añade una propiedad crítica: secreto hacia adelante y hacia atrás. Incluso si un atacante descubre el estado interno actual, no puede determinar salidas anteriores (secreto hacia atrás). Y predecir salidas futuras a partir de salidas pasadas es computacionalmente inviable sin conocer el estado.

Los CSPRNGs logran esto mediante:

CSPRNGs Comunes

Usando Aleatoriedad Criptográfica en la Práctica

En el navegador, la API Web Crypto proporciona aleatoriedad de grado criptográfico:

// Generar un entero aleatorio criptográficamente seguro
function secureRandomInt(min, max) {
  const range = max - min + 1;
  const bytesNeeded = Math.ceil(Math.log2(range) / 8);
  const maxValid = Math.floor(256 ** bytesNeeded / range) * range - 1;

  let value;
  do {
    const array = new Uint8Array(bytesNeeded);
    crypto.getRandomValues(array);
    value = array.reduce((acc, byte, i) => acc + byte * (256 ** i), 0);
  } while (value > maxValid); // Rechazar valores sesgados

  return min + (value % range);
}

// Generar una contraseña aleatoria segura
function generatePassword(length = 16) {
  const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*';
  const array = new Uint32Array(length);
  crypto.getRandomValues(array);
  return Array.from(array, x => chars[x % chars.length]).join('');
}

Prueba generar contraseñas seguras con nuestro Generador de Contraseñas, que usa la API Web Crypto para aleatoriedad de grado criptográfico.

Entropía: El Combustible de la Aleatoriedad

La entropía, en el contexto de la aleatoriedad, mide la cantidad de imprevisibilidad genuina en un sistema. Se mide en bits — un bit de entropía significa una elección binaria que un atacante no puede predecir.

¿De Dónde Viene la Entropía?

Los sistemas operativos recolectan continuamente entropía de múltiples fuentes:

We use cookies for analytics. By continuing, you agree to our Privacy Policy.