Why this does not use Math.random#
JavaScript's Math.random is a fast pseudorandom generator with a predictable internal algorithm — good enough for a visual flourish, not for anything where genuine unpredictability matters, like a raffle drawing, a fair random assignment, or picking a number nobody could have anticipated. crypto.getRandomValues draws from the operating system's cryptographically secure random source, the same category used to generate encryption keys — the actual bar for something meant to be truly unpredictable, not just statistically random-looking.
The subtler bug this avoids: modulo bias#
A common but flawed shortcut for "random number in a range" takes a random 32-bit integer and computes it modulo the range size — which is nearly right but not exact, because 2^32 is rarely a clean multiple of the requested range. That mismatch means the low end of the range gets picked very slightly more often than the high end, a bias too small to notice by eye but real and measurable over enough draws. This tool avoids it with rejection sampling: it discards any raw value that falls in the small leftover portion that would cause the bias, and draws again, guaranteeing every number in the range is exactly equally likely.
Why "no duplicates" has a hard limit#
Asking for 10 unique numbers from a range of only 5 possible values is mathematically impossible — there simply are not enough distinct numbers to satisfy the request. This tool checks that up front and explains clearly why, rather than either hanging while endlessly failing to find a new unique value or silently returning fewer numbers than asked for.