Random Number Generator
crypto.getRandomValues · uniform · in-browser
crypto.getRandomValues, the same secure source modern browsers use
for TLS keys. Rejection sampling is used so each value in the range is equally
likely; no Math.random() bias here.
Why this is “true random”
Browser Math.random() is fast but uses a deterministic
pseudo-random algorithm seeded from process entropy — fine for graphics,
not fine for picking a winner or drawing a lottery. This page calls
crypto.getRandomValues instead, which is required by the Web
Crypto specification to be a cryptographically strong RNG. On every modern
browser that means values are pulled from the operating system’s
entropy pool (/dev/urandom on Linux/macOS,
BCryptGenRandom on Windows), the same source TLS keys come
from.
Avoiding modulo bias
Naively writing bytes[0] % 6 to roll a die is slightly biased:
256 is not a multiple of 6, so values 0–3 occur 43 times each and
values 4–5 only 42 times each in a perfectly uniform sample of 256
bytes. For a die that’s ~0.5% bias — usually invisible, but it
grows quickly with larger ranges. This page uses
rejection sampling: it generates uint32 values and
discards any that fall in the “remainder” window above the
largest multiple of the range that fits. The expected number of rejections
is below one, so it’s effectively as fast as the biased version, just
correct.
Decimal mode
Decimal values are sampled by drawing 53 random bits (matching IEEE-754
double precision) to form a uniform float in [0, 1), then
affinely mapping it to your chosen [min, max] range and
rounding to the requested decimal places. This is slightly different from
the integer path because the underlying values aren’t all distinct in
floating-point — near-zero values have more representable doubles than
near-one values. For typical use (random angles, percentages, weights,
coordinates) the result is indistinguishable from a continuous uniform
distribution.
Unique mode
With No duplicates, the count is capped at the size of the range (you can’t pick 10 unique values out of 5). For small ranges the page uses a partial Fisher–Yates shuffle of the full range; for huge ranges it samples with rejection into a Set until the count is reached. Either way every k-tuple is equally likely, which is what you want for a fair lottery draw.
Privacy
Random number generation is purely arithmetic over locally-sourced bytes
— the page never makes a network request to a randomness API. There
is no fetch() for entropy, no third-party RNG service, no
analytics that watch what you generate. The numbers you draw stay in this
tab.