Random number generator 1 to 10
A random number generator for 1 to 10 that runs in your browser: one draw from 10 equally likely values, debiased so none of them is favored.
Random number
- Where this came from Your browser's cryptographically secure generator, not Math.random(). V8 implements Math.random() with xorshift128+, whose internal state can be recovered from a short run of its own output. That is fine for shuffling a playlist and unusable for anything anybody would call a secret.
- crypto.getRandomValues()
- Debiased by 2^32 is not a multiple of 10, so 6 values would get one extra chance each under plain modulo. Those words are drawn again instead of used, which costs 0.000000% of draws and makes every outcome exactly equally likely.
- rejection sampling, discarding 6 of 2^32 words
- Skew avoided How much more likely the favored outcomes would have been under
getRandomValues() % range. For small ranges it is far below anything observable; the reason to do it properly is that the same line of code is wrong by nearly 2x for ranges near 2^31, and nobody rewrites it when the range changes. - 0.00000023%
- Range size
- 10 values
- Entropy 1 independent draw from 10 values. For comparison, a six-character lowercase password carries about 28 bits and a four-word passphrase from a 7,776-word list about 51.
- 3.3 bits
- The numbers in the HTML were drawn once when the site was built, so without JavaScript every visitor sees the same ones. With JavaScript on, which is the normal case, the draw happens in your own browser, from your own generator, and nothing is sent anywhere.
How the Random Number Generator works
This generator draws one integer from 1 to 10 inclusive: 10 possible values, each with probability exactly 1 in 10.
The range people are asked for when somebody says "pick a number", and the one where human randomness fails most visibly. Asked to choose between 1 and 10, people pick 7 far more often than chance allows. It is odd, prime, not a multiple of five and not at an end, so it feels the most arbitrary and is therefore the most chosen. 1 and 10 are picked least, because the ends feel like cheating. None of that applies to a machine: each of the ten is drawn with probability exactly one tenth, and over enough draws 7 comes up no more often than 3. Ten does not divide 2^32, so this range does need debiasing: six values out of four billion get an extra chance under plain modulo, which is a skew of about one part in 715 million.
The draw happens in your browser, from crypto.getRandomValues(), which reads your operating system's cryptographically secure generator. It is not Math.random(): that is xorshift128+ in V8, fast and statistically fine for a game, and predictable to anyone who sees a short run of its output. Nothing about your draw is sent anywhere, because there is nowhere for it to be sent: the page is static and the generator is local.
A 32-bit word has 4,294,967,296 possible values and 10 does not divide it evenly; the remainder is 6. Under the usual word % 10, those 6 values would each get one extra chance, making 6 outcomes very slightly more likely than the rest. This generator rejects those words and draws again, which costs about one draw in 715,827,883 and makes the distribution exactly uniform instead of nearly so. For a range this size the skew being removed is around 2.3e-7%. That is undetectable in practice, but the same code is wrong by nearly 2x for ranges near 2^31, which is the real reason to write it correctly.
One draw from this range carries about 3.3 bits of entropy. For scale, a six-character lowercase password is roughly 28 bits and anything used as a secret wants 70 or more.
One thing about how the result reaches you: the site is statically hosted, so the number in the HTML was drawn once when the site was built. If you have JavaScript turned off, that is what you are looking at, and every other such visitor sees the same thing. With JavaScript on, the generator redraws immediately from your own browser. A generator that quietly serves one cached "random" value to everybody is broken, which is why the build-time draw is labeled.
Random Number Generator FAQ
How do I get a random number between 1 and 10?
The generator above does it on load and on every press. It draws from your browser's crypto.getRandomValues() and discards the 6 words that would skew the result before mapping it onto the 10 values.
Is every number in this range equally likely?
Yes, exactly. The 6 words that would have made some outcomes marginally likelier are rejected and redrawn, so each of the 10 outcomes ends up with exactly 429,496,729 words behind it.
Is there anything particular about this range?
The range people are asked for when somebody says "pick a number", and the one where human randomness fails most visibly. Asked to choose between 1 and 10, people pick 7 far more often than chance allows. It is odd, prime, not a multiple of five and not at an end, so it feels the most arbitrary and is therefore the most chosen. 1 and 10 are picked least, because the ends feel like cheating. None of that applies to a machine: each of the ten is drawn with probability exactly one tenth, and over enough draws 7 comes up no more often than 3. Ten does not divide 2^32, so this range does need debiasing: six values out of four billion get an extra chance under plain modulo, which is a skew of about one part in 715 million.
Can I rely on it not being predictable?
For anything short of a regulated draw, yes. The source is the same operating-system facility that generates cryptographic keys. The limit worth knowing is that it is a CSPRNG seeded from hardware entropy rather than a hardware true-random device sampling a physical process, and no software running in a browser tab can be the latter.
More from the Random Number Generator
- Random number generator 1 to 100
- Random number between 1 and 6
- Random number from 1 to 2
- Random number generator 1 to 1000
- Random number generator 1-49: pick 6
- Bingo caller
- Lottery number generator