Hay un patrón común en el código donde un programador elige un elemento aleatorio de una lista generando un número grande y reduciéndolo módulo el número de opciones: `choice = items[rng() % n]`. La entrada del blog muestra por qué esto no brinda a cada elemento la misma oportunidad. Si el generador de números aleatorios produce valores uniformemente del 0 al 9 (diez posibilidades) y se quiere elegir uno de tres objetos, la asignación es: valores {0,3,6,9} → primer objeto, {1,4,7} → segundo, {2,5,8} → tercer objeto. De este modo, el primer objeto se selecciona 4 de cada 10 veces (40 %), mientras que los otros dos aparecen cada uno solo 3 de cada 10 veces (30 %). Esta pérdida de uniformidad se denomina sesgo de módulo.

La forma correcta de preservar la uniformidad es utilizar una función que devuelva un entero uniformemente distribuido en un rango deseado, como `random_between(l, h)`. Para tres opciones se llamaría a `random_between(0,2)` y se asignaría el resultado directamente. Una API más expresiva es `random_choice(options)` que acepta pesos enteros relativos; por ejemplo `[(A,4),(B,3),(C,3)]` produce la misma distribución 40/30/30 cuando esa es realmente la intención, pero permite al programador especificar las probabilidades deseadas explícitamente. La entrada señala que la mayoría de las bibliotecas estándar (por ejemplo, `random.randrange` de Python) ya implementan este enfoque, y que contar con `random_between` disponible facilita la construcción de `random_choice`.

Diagrama que muestra el sesgo de módulo en la selección aleatoria con diez valores asignados a tres resultados
Ilustración de cómo la operación módulo provoca una distribución desigual al seleccionar elementos aleatoriosersc.io

La imagen visualiza el ejemplo de sesgo de módulo descrito en el artículo, donde diez valores aleatorios se asignan de manera desigual a tres opciones, provocando probabilidades de selección del 40% y el 30%.

En Antithesis, el equipo del autor revisó su código de fuzzing y reemplazó cada llamada ad‑hoc `random_u64() % n` por un auxiliar `weighted_choice` que impulsa la distribución del tamaño de los blobs (por ejemplo, 88 % pequeño, 4 % medio, 4 % grande y 4 % extra grande). Este cambio eliminó una fuente oculta de sesgo no determinista en su cobertura de pruebas y provocó una moratoria sobre nuevos usos de `random_u64()` hasta que esté disponible una mejor abstracción. El episodio ilustra cómo una aparente conveniencia inocua puede distorsionar los experimentos aleatorizados y por qué es preferible una API de nivel superior que revele la intención.