How to generate random numbers that are actually uniform
Set a range, pick how many numbers you want, and get a draw where every value has the same chance of showing up.
Most random number pickers on the web run Math.floor(Math.random() * (max - min + 1)) + min and call it done. That line is close enough for a background animation and wrong for a raffle. The random number generator uses the browser cryptographic random source and throws away the draws that would skew the result.
How it works
- Type a minimum and maximum, or click a preset: dice for 1 to 6, coin for 1 to 2, lottery for six numbers from 60, percentage for 1 to 100.
- Choose the quantity, up to 1000, and whether repeats are allowed. Switch to decimal mode if you need fractions.
- Press Generate. Copy one value with the button beside it, or the whole list with Copy all.
Where modulo bias comes from
A browser gives you 32 random bits at a time, which is a number from 0 to 4,294,967,295. To turn that into a number from 1 to 100 the tempting move is value % 100. But 4,294,967,296 divided by 100 leaves a remainder of 96. The residues 0 through 95 each appear one extra time in that span, so those outcomes are about 0.000002% more likely than the rest.
At a hundred draws nobody notices. At a hundred million draws it shows up in the histogram, and for small entropy sources rather than 32-bit ones the skew gets much worse. The standard fix is rejection sampling: compute the largest multiple of 100 that fits under 4,294,967,296, discard any draw at or above it, and redraw. You waste a draw roughly once every 45 million attempts and the distribution comes out flat.
Why not Math.random
V8 implements Math.random with xorshift128+, seeded once per context from an unspecified source. It is fast and its output looks fine, but it is predictable given enough observed values, and browsers make no promise about its quality. crypto.getRandomValues pulls from the operating system entropy pool, the same one that seeds TLS keys. It costs a few microseconds more and removes the whole question.
None of this makes the tool suitable for regulated gambling or an official lottery. Those need certified hardware and an audit trail. It does make it fine for picking a giveaway winner, seeding test data, or settling an argument.
Drawing without repeats
Untick "allow duplicates" and the draw happens without replacement. The naive approach keeps a set and redraws on a collision, which works until the quantity approaches the size of the range. Asking for all 60 lottery balls that way means the last few draws spend thousands of attempts hunting for the numbers not yet taken.
Instead the generator runs a partial Fisher-Yates shuffle over a sparse map, which produces the requested count in exactly that many steps no matter how full the range gets. And when you ask for 10 unique numbers between 1 and 5, it says so and stops, rather than spinning forever on a request that has no answer.
Decimals
Decimal mode does not multiply a random float by the range. It scales the bounds to integers at the precision you asked for, draws an integer uniformly across that larger space, then divides back down. Ask for two places between 0 and 1 and you get an even draw across 101 possible values, with no clustering caused by floating point spacing near zero.