Random Number Generator
Draw crypto-random numbers in your browser — any range, unique lottery-style picks, decimals, and dice from d4 to d20, with no modulo bias.
How it works
- 1
Set the range
Enter the smallest and largest value you want — both ends can come up, and negative numbers are fine. The default 1 to 100 covers the everyday pick-a-number case, and the range can span up to 4,294,967,296 values, the width of one 32-bit draw.
- 2
Shape the draw
Choose how many values to produce (up to 100), and switch on unique mode to draw without replacement when the values must all differ — a raffle, a draft order, a random sample. Decimals mode draws values with up to six decimal places instead of whole numbers; unique and decimals are alternatives, since a repeated-value guarantee only makes sense over whole numbers.
- 3
Or roll dice
Dice mode rolls any number of dice from d4 to d20 in one press — 2d6 for a board game, 4d6 for character creation, a d20 for the decisive check. Each die is an independent draw and the total is summed for you.
- 4
Roll, re-roll, copy
Every value lands as its own chip; click a chip to copy that value alone, or copy the whole set at once. Re-roll draws a completely fresh set from the cryptographic source — previous results are never reused or remembered.
A worked roll: two six-sided dice, [1, 6], total 7
Switch the tool to dice mode, set the count to 2 and the die to d6, and press Roll. One particular press of this page produced [1, 6] — a 1 on the first die and a 6 on the second, a total of 7. That roll is not an illustration; it is output the generator actually returns for those draws, and the test suite pins it: the sequence of raw draws that maps to 1 and then to 6 must come out as dice [1, 6] with total 7, every time that sequence is fed through.
| Setting | Value |
|---|---|
| Mode | Dice |
| Dice | 2 × d6 |
| Result | [1, 6] |
| Total | 7 |
The same engine serves every other mode. Switch to numbers and set a range of 1 to 6 with a count of 2, and the two draws that made that roll come back as the pair 1 and 6 — dice mode is nothing more than range mode with the range fixed at 1 to the number of sides and the total summed for you. The chance of a total of 7 on two fair d6 is 6 in 36, one in six, the most likely total on the pair; but each individual roll is a fresh unbiased draw, and the value that turns up owes nothing to the one before it.
Where the randomness comes from
Every draw on this page starts at crypto.getRandomValues, the browser's cryptographic random source. Underneath, that call reaches the operating system's entropy pool, which mixes hardware event timing, interrupt noise and other unpredictability into a state no page can inspect or set. The browser then sits between the page and the pool: a page cannot read the raw state, influence it, or ask for values it has seen before. What comes back is the strongest randomness a web page can obtain — the same source browser password managers draw from when they generate credentials.
That raw draw is a 32-bit integer, one of 4,294,967,296 equally likely cells. Turning cells into numbers in your range is where the real design work sits, because the obvious translation — divide and take the remainder — quietly hands some values more weight than others. The next section walks through that failure and the fix, and the fix is small enough to state in one line: draws that land in the leftover stub are discarded and replaced before they can skew anything.
The stub at the end of the strip, and what it would skew
Take the strip of 4,294,967,296 cells and cut it into rows the length of your range. When the division is not exact, a stub of leftover cells hangs off the end, and its size is the remainder of 4,294,967,296 divided by your range. The remainder trick pretends the stub does not exist and folds it onto the first values of the range — each of those values then carries one extra cell of probability per stub cell. How much that matters depends entirely on how big the stub is next to the range:
| Range | Leftover cells | What naive remainder mapping does |
|---|---|---|
| 10 | 6 | faces 1–6 gain one cell in 429 million of weight — real, but unmeasurable |
| 1,000,000 | 967,296 | the first 967,296 values gain about 0.02% weight |
| 4,000,000,001 | 294,967,295 | the first 295 million values become twice as likely as the rest |
The sampler behind this tool computes how many whole rows fit — 429,496,729 of them for a range of 10 — and treats only that territory as valid. A raw draw landing in the stub is thrown away and drawn again; the cost is one extra draw roughly once per 716 million rolls at that range, and about one draw in fourteen at the near-2^32 range where the stub is enormous. What it buys is exactness: every value in the range is backed by an identical number of cells, so the histogram comes out flat not approximately but by construction. That property is what the uniformity test in the tool's own test suite holds the line on — sixty thousand draws across a ten-value range, every bucket required to sit within three percent of its fair share.
Unique draws layer one more guarantee on top. Because each swap in the shuffle uses the same bias-free sampler, no position in the pool is privileged, so no subset of winners is more likely than any other — the fairness of the draw inherits directly from the fairness of the individual draws, with no repeats possible anywhere in the process.
Frequently asked questions
Why can't I just use Math.random() for a giveaway or draft?
What is modulo bias, actually?
What is the difference between crypto-random and statistical randomness?
How does a lottery-style draw stay fair?
Who knows the numbers before I do?
Related tools
Last updated: October 10, 2026