Números Pseudoaleatorios · Tema 03

Números aleatorios en una computadora

Por qué una máquina determinista no puede «tener azar», de dónde saca entropía el sistema operativo y qué usa realmente tu random.random().

01 · Punto de partida

La paradoja: pedir azar a lo determinista

Una computadora es determinista por diseño: el mismo programa, con los mismos datos, produce el mismo resultado. Esa es su virtud para calcular nóminas o compilar código. Pero para simular necesitás lo contrario: variabilidad, miles de valores distintos que parezcan azar.

En el Tema 2 viste la salida conceptual: un algoritmo pseudoaleatorio. Ahora toca la salida práctica: ¿de dónde sale la primera semilla si todo es determinista? ¿Qué hace Python cuando no fijás seed? ¿Cuándo hay azar físico real y cuándo es solo cálculo?

  • ¿Por qué random.random() da distintos valores en cada ejecución si no fijaste semilla?
  • ¿Qué es la entropía del sistema y dónde la consigue tu PC?
  • ¿Qué diferencia hay entre random, secrets y os.urandom?
  • ¿Cuándo te conviene cada uno?

02 · Definición

Determinismo, entropía y los dos generadores

Todo el ecosistema se entiende con tres palabras:

◈

Determinismo

Misma entrada, misma salida. Es lo que permite depurar: si repetís semilla y código, repetís la simulación completa.

⇄

Entropía

Imprevisibilidad que viene de afuera del cálculo: instante exacto de una tecla, microvariación térmica, tiempo entre paquetes de red.

▣

TRNG frente a PRNG

TRNG (True Random Number Generator, generador de números verdaderamente aleatorios) mide entropía física; PRNG (Pseudorandom Number Generator, generador de números pseudoaleatorios) calcula desde una semilla. El sistema combina ambos: entropía para sembrar, PRNG para producir en masa.

Los dos mundos, frente a frente.
AspectoTRNG / entropía del sistemaPRNG (random)
FuenteHardware y eventos del SOFórmula + semilla
¿Repetible?NoSí, con la misma semilla
VelocidadLenta, recurso escasoMillones de valores/s
Ejemplosos.urandom, RDRAND, /dev/randomrandom.Random, NumPy, Mersenne Twister

03 · Por dentro de tu PC

De dónde saca entropía el sistema

Tu sistema operativo mantiene una «pileta» de entropía que mezcla eventos impredecibles en detalle. Cuando Python arranca sin semilla explícita, toma de ahí el punto de partida:

Tiempos
Instante exacto de teclas, clics, discos y red, medidos en nanosegundos. No es el «segundo» del reloj, sino la microvariación imposible de replicar.
Ruido de hardware
Fluctuaciones térmicas y eléctricas, instrucciones como RDRAND/RDSEED en CPUs modernas que exponen azar físico al SO.
Pileta del SO
Linux expone /dev/random y /dev/urandom; Windows, su API criptográfica. Python bebe de ahí vía os.urandom para la semilla inicial.
Reloj como último recurso
Usar «la hora en segundos» como semilla es lo más pobre: dos ejecuciones en el mismo segundo repiten todo y un adversario la adivina. Solo vale para jugar.

Buena siembra

Entropía del SO

Cada ejecución parte de un punto distinto e impredecible, pero una vez sembrado el PRNG, la secuencia es reproducible si guardás la semilla.

Siembra pobre

Hora en segundos

Funciona para un demo, pero colisiona fácil, se predice y arruina la reproducibilidad seria. Nunca para seguridad ni para publicar ciencia.

04 · Mapa

Qué usa realmente tu código Python

En Python conviven tres herramientas con propósitos distintos. Confundirlas es fuente clásica de bugs de seguridad y de ciencia irreproducible:

Entropía del SO→Semilla→PRNG veloz
  1. 1
    random: el caballo de simulación.

    PRNG Mersenne Twister, rapidísimo, con semilla fijable. Ideal para réplicas, escenarios y depuración. No apto para seguridad.

  2. 2
    secrets: el de seguridad.

    Bebe del generador criptográfico del SO, no admite semilla. Para contraseñas, tokens y sorteos con adversario.

  3. 3
    os.urandom / SystemRandom: el puente.

    Bytes crudos de entropía o un random alimentado por el SO. Útil para sembrar a mano tus propios generadores.

  4. 4
    NumPy (default_rng): el de ciencia masiva.

    Generadores modernos (PCG) vectorizados para millones de valores. Lo verás en el Tema 17; la lógica semilla→secuencia es la misma.

05 · Demostración en Python

Semilla fija frente a entropía del sistema

Este bloque demuestra el determinismo de random: con semilla fija se repite; sin fijarla, cada ejecución parte de entropía del sistema y cambia.

Python en tu navegador. En Pyodide, la semilla inicial también viene del navegador. Fijarla con seed te devuelve el control.

import random

random.seed(2026)
print("fija:", [round(random.random(), 4) for _ in range(5)])
random.seed(2026)
print("fija otra vez:", [round(random.random(), 4) for _ in range(5)])

Dos listas idénticas: el PRNG no consultó ningún azar físico entre una y otra, solo repitió el cálculo.

Bytes que nunca se repiten

En cambio, os.urandom pide entropía fresca al sistema en cada llamada. Ejecutalo varias veces y compará:

import os

print(os.urandom(8).hex())
print(os.urandom(8).hex())

06 · Exploración

Laboratorio: tres fuentes, tres comportamientos

Elegí la fuente y la cantidad de valores. La curva muestra los valores en [0,1) en orden de generación. Generá dos veces seguidas con cada fuente y observá cuál se repite y cuál no.

EXPERIMENTO 03

¿De dónde viene tu azar?

fija · hora · navegador

Los resultados numéricos aparecen debajo.
Primer valor (corrida 1)—
Primer valor (corrida 2)—
¿Se repitió?—
Tipo—

Generá dos veces con semilla fija: verás repetición exacta.

La superposición de dos corridas solo ocurre con semilla fija. La hora cambia entre clics y el azar del navegador nunca se repite igual.

Preguntas para explorar

  1. Con semilla fija, generá 3 veces: ¿cambia algún punto? ¿Qué ventaja da eso para depurar?
  2. Con semilla = hora, generá 2 veces rápido: ¿a veces coinciden? ¿Por qué el reloj en segundos es mala semilla?
  3. ¿Cuál fuente elegirías para publicar un paper y cuál para generar un token secreto?
Ver respuestas sugeridas
  1. No cambia nada: es el mismo cálculo. Podés reproducir un bug o compartir el experimento con un solo número.
  2. Pueden coincidir si ambos clics caen en el mismo milisegundo o si el reloj es grueso: colisión de semillas. Por eso no sirve para seguridad.
  3. Paper: semilla fija documentada (PRNG). Token: entropía del sistema (secrets), sin semilla fijable.

07 · Comprensión

Confusiones frecuentes

«Sin seed hay azar verdadero»

No: sin seed Python siembra el PRNG con entropía del SO, pero después todo es cálculo determinista. Cambia por corrida, pero no es un TRNG por llamada.

«Semilla = hora actual ya es seguro»

La hora se adivina fácil y colisiona. Un atacante que conoce el día y el algoritmo prueba pocas semillas y reproduce tus «secretos». Para seguridad, secrets.

«random sirve para contraseñas si nadie mira»

random es predecible por diseño una vez vista una parte de la secuencia (Mersenne Twister se puede clonar). Las contraseñas y tokens exigen el generador del SO.

«Más entropía = mejor simulación»

Para simular, lo mejor es lo contrario: entropía una sola vez para elegir semilla y después determinismo total documentado. Ciencia = repetición, no sorpresa por corrida.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: la semilla manda

Ejecutá, anotá la salida, volvé a ejecutar. Luego quitá la línea de seed y repetí. ¿Qué cambia?

import random

random.seed(7)
print([random.randint(1, 10) for _ in range(5)])
Ver solución razonada

Con seed(7) siempre sale lo mismo en cualquier máquina y momento. Sin seed, cada ejecución parte de entropía distinta y cambia: útil para variar, inútil para reproducir.

Ejercicio 2: contraseña con secrets

Generá un token con el módulo de seguridad y observá que no hay forma de fijar semilla: esa es la garantía.

import secrets
import string

alfabeto = string.ascii_letters + string.digits
pwd = "".join(secrets.choice(alfabeto) for _ in range(12))
print(pwd)
Ver solución

Cada ejecución da un token distinto y no existe secrets.seed(). Si necesitás repetirlo, guardalo; no intentes «reproducirlo» con semilla.

Ejercicio 3: experimento reproducible

Empaquetá tu corrida con semilla y versión para que otro pueda repetirla bit a bit. Este patrón lo usarás en el Tema 36.

Ver una posible respuesta
import random

EXPERIMENTO = {"semilla": 2026, "n": 5, "version": "tema3-v1"}

random.seed(EXPERIMENTO["semilla"])
print(EXPERIMENTO)
print([random.random() for _ in range(EXPERIMENTO["n"])])

Publicar el diccionario EXPERIMENTO junto a los resultados convierte tu simulación en repetible. Sin semilla anotada, el resultado es anecdótico.

09 · Síntesis

Ideas para recordar

  • La computadora es determinista: el azar masivo sale de un PRNG, no de magia del hardware.
  • La entropía (tiempos, ruido, pileta del SO) solo sirve para elegir la semilla inicial.
  • random = simulación repetible; secrets/os.urandom = seguridad no repetible.
  • Sin seed hay variedad entre corridas, pero por dentro sigue habiendo determinismo.
  • Hora en segundos como semilla es pobre: colisiona y se predice.

En el próximo tema definiremos con precisión el objeto central del curso: las secuencias pseudoaleatorias, sus propiedades y cómo leerlas como salida de un generador.