Números Aleatorios en JavaScript: Math.random()
Aprende a generar números aleatorios en JavaScript con Math.random(), desde números básicos hasta rangos específicos y aplicaciones prácticas.
TL;DR - Resumen rápido
- Math.random() retorna [0, 1): puede ser 0 pero nunca exactamente 1
- Enteros [min, max] inclusivos: Math.floor(Math.random() * (max - min + 1)) + min
- NUNCA uses Math.random() para seguridad (tokens, contraseñas): es predecible
- Usa crypto.getRandomValues() para aleatoriedad criptográficamente segura
- Algoritmo Fisher-Yates para mezclar arrays: evita sesgos de shuffle ingenuo
Introducción a Math.random()
Math.random() es el método principal de JavaScript para generar números pseudoaleatorios. Este método retorna un número de punto flotante entre 0 (inclusive) y 1 (exclusivo), lo que significa que puede retornar 0 pero nunca retornará 1. Aunque los números generados son técnicamente "pseudoaleatorios" (siguen un algoritmo determinista), son suficientemente aleatorios para la mayoría de aplicaciones cotidianas.
La generación de números aleatorios es fundamental en muchas aplicaciones: juegos, simulaciones, pruebas automatizadas, selección aleatoria de elementos, y más. Sin embargo, es importante entender las limitaciones de Math.random() y cuándo no debería usarse, especialmente en contextos de seguridad donde se requiere aleatoriedad criptográficamente segura.
- Genera números entre 0 (inclusive) y 1 (exclusivo)
- Los números son pseudoaleatorios, no verdaderamente aleatorios
- No es adecuado para criptografía o tokens de seguridad
- El algoritmo varía entre navegadores y motores JavaScript
- Para usos criptográficos, usa crypto.getRandomValues() de la Web Crypto API
Historia de Math.random()
Math.random() existe desde ES1 (ECMAScript 1997). El algoritmo específico utilizado no está especificado en el estándar ECMAScript, lo que significa que diferentes implementaciones (V8, SpiderMonkey, JavaScriptCore) pueden usar algoritmos diferentes. Esto puede resultar en secuencias de números aleatorios diferentes entre navegadores.
Funcionamiento Básico de Math.random()
Math.random() no acepta parámetros y siempre retorna un número en el rango [0, 1). Cada llamada independiente genera un nuevo número aleatorio. Es importante entender que "0 (inclusive)" significa que Math.random() puede retornar exactamente 0, pero "1 (exclusivo)" significa que nunca retornará exactamente 1, aunque puede retornar valores muy cercanos a 1 como 0.9999999999999999.
El ejemplo muestra múltiples llamadas a Math.random() para demostrar la variabilidad de los resultados. Cada llamada genera un número diferente dentro del rango especificado. Note que los valores pueden ser muy cercanos a 0 o a 1, pero nunca exactamente 1.
Generación Reproducible para Pruebas
Para pruebas unitarias, a veces necesitas números aleatorios reproducibles. Algunos motores JavaScript permiten "sembrar" el generador de números aleatorios, pero esto no es parte del estándar ECMAScript. Para reproducibilidad en pruebas, considera usar una biblioteca de mock o implementar tu propio generador con semilla.
Generar Números Enteros en un Rango
Una de las operaciones más comunes con Math.random() es generar números enteros dentro de un rango específico, como lanzar un dado (1-6), seleccionar un índice de array, o generar un número de puerto. La fórmula estándar para esto combina Math.random(), Math.floor() y aritmética básica.
Entero entre 0 y max (inclusive)
Para generar un entero entre 0 y un número máximo (ambos inclusive), la fórmula es Math.floor(Math.random() * (max + 1)). El +1 es necesario porque Math.random() nunca retorna 1, por lo que Math.random() * max nunca sería igual a max.
Este ejemplo genera números enteros entre 0 y el máximo especificado. La fórmula Math.floor(Math.random() * (max + 1)) garantiza que el resultado esté en el rango [0, max] inclusive.
Entero entre min y max (inclusive)
Para generar un entero en un rango arbitrario [min, max], la fórmula es Math.floor(Math.random() * (max - min + 1)) + min. Esta fórmula primero genera un número entre 0 y (max - min), y luego suma min para desplazar el rango al intervalo deseado.
La función getRandomInt(min, max) es la forma más común de generar enteros aleatorios en un rango específico. El ejemplo muestra cómo usarla para simular un dado de 6 caras y seleccionar elementos aleatorios de un array.
Advertencia: Sesgo en Distribuciones
Math.random() genera números con distribución uniforme, pero cuando los conviertes a enteros, asegúrate de que el rango sea divisible por el número de posibles resultados para evitar sesgos. Para aplicaciones que requieren distribución estadística perfecta, considera bibliotecas especializadas.
Generar Números Decimales en un Rango
A veces necesitas números decimales aleatorios en un rango específico, como coordenadas geográficas, valores de temperatura simulados, o porcentajes aleatorios. La fórmula para esto es más simple que para enteros: Math.random() * (max - min) + min.
La función getRandomFloat(min, max) genera números decimales en el rango [min, max). Note que el rango es semiabierto: incluye min pero excluye max. Si necesitas incluir ambos extremos, puedes usar una fórmula ligeramente diferente o agregar una pequeña cantidad al resultado.
Control de Precisión de Decimales
Para controlar cuántos decimales tiene el número aleatorio, puedes combinar Math.random() con métodos de redondeo. Esto es útil cuando necesitas valores con precisión específica, como precios con dos decimales o coordenadas con cierta resolución.
Este ejemplo muestra cómo generar números aleatorios con un número específico de decimales. La técnica consiste en generar el número, multiplicar por 10^n, redondear, y luego dividir por 10^n.
Aplicaciones Prácticas
Los números aleatorios tienen numerosas aplicaciones en desarrollo web. Desde juegos y simulaciones hasta pruebas automatizadas y selección de contenido, Math.random() es una herramienta versátil que resuelve muchos problemas comunes de programación.
Selección Aleatoria de Elementos
Una de las aplicaciones más comunes es seleccionar un elemento aleatorio de un array. Esto es útil para mostrar contenido aleatorio, seleccionar ganadores en sorteos, o crear sistemas de recomendación simples.
Las funciones getRandomElement y shuffleArray demuestran patrones comunes para trabajar con colecciones aleatorias. La función shuffle usa el algoritmo Fisher-Yates, que es el método estándar para mezclar arrays de manera eficiente y no sesgada.
Generación de Colores Aleatorios
Generar colores aleatorios es útil para prototipos, visualizaciones de datos, y efectos visuales. Puedes generar colores en diferentes formatos: RGB, HEX, HSL, según las necesidades de tu aplicación.
Este ejemplo muestra cómo generar colores aleatorios en formato RGB y HEX. El formato RGB es más fácil de manipular programáticamente, mientras que HEX es más común en CSS y diseño web.
Simulaciones y Probabilidades
Math.random() es ideal para simular eventos probabilísticos. Puedes modelar eventos con cierta probabilidad de ocurrencia, como aciertos en juegos, decisiones aleatorias en IA, o simulaciones Monte Carlo.
Las funciones de probabilidad demuestran cómo modelar eventos con diferentes chances de ocurrencia. La función simulateEvent es especialmente útil para juegos y simulaciones donde necesitas controlar la frecuencia de ciertos eventos.
Simulación Monte Carlo
Las simulaciones Monte Carlo usan números aleatorios para aproximar resultados numéricos complejos. Por ejemplo, puedes estimar el valor de PI generando puntos aleatorios en un cuadrado y contando cuántos caen dentro de un círculo inscrito. Esta técnica se usa ampliamente en física, finanzas e ingeniería.
Limitaciones y Consideraciones
Aunque Math.random() es adecuado para muchas aplicaciones, tiene limitaciones importantes que debes conocer. La más crítica es que no es criptográficamente seguro, lo que significa que no debe usarse para generar contraseñas, tokens de seguridad, o cualquier valor donde la aleatoriedad predecible podría ser explotada.
Este ejemplo muestra la diferencia entre Math.random() y crypto.getRandomValues(). La Web Crypto API proporciona aleatoriedad criptográficamente segura que es adecuada para generar tokens, IDs de sesión, y otros valores sensibles.
- <strong>No criptográficamente seguro:</strong> Los valores son predecibles con suficiente conocimiento del algoritmo
- <strong>Pseudoaleatorios:</strong> Sigue un algoritmo determinista, no verdadera aleatoriedad
- <strong>Varía por implementación:</strong> Diferentes navegadores pueden generar secuencias diferentes
- <strong>Para seguridad:</strong> Usa crypto.getRandomValues() de la Web Crypto API
- <strong>Para semillas reproducibles:</strong> Considera bibliotecas especializadas como seedrandom
Advertencia de Seguridad Crítica
NUNCA uses Math.random() para generar contraseñas, tokens de autenticación, claves de API, o cualquier valor relacionado con seguridad. Estos valores deben generarse con aleatoriedad criptográficamente segura usando crypto.getRandomValues() o una biblioteca criptográfica confiable. Los atacantes pueden predecir valores generados con Math.random() si conocen suficientes valores anteriores.
Resumen: Números Aleatorios en JavaScript
Conceptos principales:
- •Math.random() genera números entre 0 (inclusive) y 1 (exclusivo)
- •Para enteros en [min, max]: Math.floor(Math.random() * (max - min + 1)) + min
- •Para decimales en [min, max): Math.random() * (max - min) + min
- •Los números son pseudoaleatorios, no criptográficamente seguros
- •La distribución es uniforme pero puede tener sesgos en conversiones
Mejores prácticas:
- •Usa Math.random() para juegos, simulaciones y prototipos
- •Para seguridad, usa crypto.getRandomValues() de Web Crypto API
- •Para pruebas reproducibles, considera generadores con semilla
- •Controla la precisión de decimales con métodos de redondeo
- •Usa el algoritmo Fisher-Yates para mezclar arrays eficientemente