CompoundPage

Random number generator 1 to 100

A random number generator for 1 to 100 that runs in your browser: one draw from 100 equally likely values, debiased so none of them is favored.

For bingo, balls to call; for a lottery, lines (up to 20).

Draw without replacement, the way a lottery does.

Random number65

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 100, so 96 values would get one extra chance each under plain modulo. Those words are drawn again instead of used, which costs 0.000002% of draws and makes every outcome exactly equally likely.
rejection sampling, discarding 96 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.00000233%
Range size
100 values
Entropy 1 independent draw from 100 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.
6.6 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 100 inclusive: 100 possible values, each with probability exactly 1 in 100.

The default range for a percentage, a guessing game, or a sample from a hundred-item list. A hundred does not divide 2^32 either. The remainder is 96, so 96 of the four billion possible words are rejected and redrawn, a rate of about one in 44 million. The useful property of this range is that it is big enough for the number to feel genuinely unpredictable and small enough to hold in your head, which is why it is the one most quizzes and classroom exercises land on.

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 100 does not divide it evenly; the remainder is 96. Under the usual word % 100, those 96 values would each get one extra chance, making 96 outcomes very slightly more likely than the rest. This generator rejects those words and draws again, which costs about one draw in 44,739,243 and makes the distribution exactly uniform instead of nearly so. For a range this size the skew being removed is around 0.0000023%. 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 6.6 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 100?

The generator above does it on load and on every press. It draws from your browser's crypto.getRandomValues() and discards the 96 words that would skew the result before mapping it onto the 100 values.

Is every number in this range equally likely?

Yes, exactly. The 96 words that would have made some outcomes marginally likelier are rejected and redrawn, so each of the 100 outcomes ends up with exactly 42,949,672 words behind it.

Is there anything particular about this range?

The default range for a percentage, a guessing game, or a sample from a hundred-item list. A hundred does not divide 2^32 either. The remainder is 96, so 96 of the four billion possible words are rejected and redrawn, a rate of about one in 44 million. The useful property of this range is that it is big enough for the number to feel genuinely unpredictable and small enough to hold in your head, which is why it is the one most quizzes and classroom exercises land on.

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

Related calculators

Embed this calculator
<div id="compoundpage-random-number-generator"></div>
<script src="https://compoundpage.com/embed/random-number-generator.js" async></script>

The same calculation as JSON