Random Number Generator_
Pick a random number between 1 and 100, roll a die, draw raffle winners without repeats, or produce ten thousand random decimals for a test fixture. Integers well past 2⁵³, decimals, weighted distributions, odd/even filters, exclusions, sorting, and your choice of separator or export format.
Every draw happens in your browser, using the cryptographically secure generator built into it. No server picks your numbers, and there is no rate limit or server-side quota — the only ceiling is 10,000 values per draw, which keeps every draw instant. Nothing about your raffle, your test data or your dice leaves this page, and when a result has to stand up to scrutiny, the commit–reveal provable draw lets anyone re-run it and check.
Weighted draws come from crypto.getRandomValues too — never Math.random() — and values outside your range are redrawn rather than clamped onto the endpoints.
Seeded mode swaps the CSPRNG for a deterministic PRNG (SFC32, seeded by hashing your seed text). Anyone holding the seed reproduces this exact draw: auditable, not unpredictable. Never use it where the result must be unguessable.
Distribution — histogram + uniformity tests on your draw
Provable draw — commit first, draw second, anyone can verify
Step 1 shows only the SHA-256 commitment of a fresh 256-bit seed plus every parameter; publish it — post, chat message, email — before you draw. Step 2 draws and reveals the seed, and anyone can replay it — paste the record into the verifier below, in this page, or run the same check in their own code.
Provable draws are uniform only: verification replays your numbers bit-for-bit in someone else's browser, and the weighted distributions need log/exp, which are not specified to the last bit across JavaScript engines. Set Distribution back to Uniform to commit.
Committed parameters (the exact bytes hashed above):
Paste any draw record here. This recomputes the commitment hash from the revealed seed and parameters, then replays the draw and compares every value with the published list — two independent checks, both in this tab, and they work with the network switched off.
Proves: the parameters and the seed were fixed before the draw, so nobody re-rolled until they liked the winner — provided the commitment was published before the draw. Does not prove: that the seed was unpredictable to whoever ran the draw. A commitment is a promise about timing, not about entropy. Still not certified for regulated gambling.
Dice notation — 4d6kh3, 2d20kl1, d6!, 2d8+1d4+3
kh/kl keep the highest/lowest N, dh/dl drop them, ! explodes a die (a maximum roll adds another, up to 100). Dropped dice show in parentheses; same CSPRNG as the main generator.
Draw history — last 10 draws this session
- Input
- Any two integer bounds — negative, positive or mixed-sign — plus how many values you want. Or a dice expression like
4d6kh3. - Output
- Up to 10,000 values, copied or downloaded as plain text, JSON, CSV, one per line, a JavaScript array, a Python list or SQL VALUES.
- Processing
- In this tab, from
crypto.getRandomValues, mapped onto your range by rejection sampling — never by a modulo reduction. - Limits
- 10,000 values per draw · integer bounds to 308 digits · decimals to 9 places · no rate limit, because no server is involved.
- Reproducible
- Optional seeded mode and a commit–reveal record anyone can replay offline — off by default, so ordinary draws stay unpredictable.
What a random number generator does when you press Generate
From operating-system entropy to your range
Generate asks the browser’s cryptographic generator — crypto.getRandomValues, reseeded continuously by the operating system from hardware events — for raw 32-bit values. Those reach your range by rejection sampling: a value landing in the biased tail of the range arithmetic is discarded and redrawn, so every number from minimum to maximum is exactly equally likely. Spans wider than a 32-bit word take as many words as they need and assemble them with BigInt arithmetic, which is why bounds of hundreds of digits stay exact and why negative and mixed-sign ranges need no special case.
Cryptographically secure, and not the same as truly random
It depends which kind you ask about, and honest tools say which kind they are. A cryptographically secure generator — what this page uses, weighted distributions included — is algorithmic but constantly reseeded from physical entropy, and designed so that predicting the next value is computationally infeasible. Hardware generators measure a physical process instead: random.org samples atmospheric radio noise, which matters for lab-grade physics and not for picking a winner. We will not call this page “truly random”, because that term belongs to physical processes; what it is, is fair, uniform and unpredictable — and the Distribution panel measures that on your own numbers rather than asking for trust.
Proving a draw was fair, without a server
“Provably fair” draw services are server-side, account-based and usually paid — their infrastructure is what you end up trusting. The Provable draw panel runs the same commit–reveal protocol in your tab, and its verifier replays a published record offline. That proves nobody re-rolled after seeing the result, provided the commitment was published first; it does not prove the seed was unpredictable to the organiser, and we will not pretend otherwise. Both the mapping and the shuffle reject-sample rather than reducing a seed with seed % (i + 1), the modulo-biased pattern in more than one published “provably fair” pseudocode.
Generating in the tab instead of on a server
Most random number generator sites compute your numbers on their server, so a draw with money or credibility attached rests on machines you cannot inspect. Here the numbers exist only in your tab, tool processing makes no outbound requests, and the page installs as an offline app that keeps drawing with the network disconnected — no rate limit, because no server is doing the work.
Writing the draw yourself, and the two traps
Every tutorial teaches Math.floor(Math.random() * (max − min + 1)) + min. Two caveats: that generator is not cryptographically secure, and the usual “secure” upgrade — a raw word taken modulo the range size — introduces the modulo bias described in the gotchas below. Rejection sampling is the fix. Spreadsheets need no code: =RANDBETWEEN(1,100), =RAND(), or =RANDARRAY(10,1,1,100,TRUE) for a column — all recalculating on every edit, so paste-as-values to freeze a draw.
Set a range, a count, and whether numbers may repeat
- 01Set the range. Type a minimum and maximum — negative and mixed-sign are fine, and bounds are not capped at 2⁵³ — or tap a preset: 1–100 is the default, with 1–10, 1–3, a d6 and a d20 one tap away.
- 02Choose how many numbers you need, up to 10,000. “No repeats” draws without replacement, “Sort ascending” tidies the order, and the Exclude field drops disqualified entries.
- 03Pick Integers or Decimals, and a distribution if you need one. Uniform is the default and the only one that supports “No repeats”; the six weighted distributions draw from the same CSPRNG, truncated to your range.
- 04Hit Generate, or press Enter in any field to re-roll. Open Distribution for a histogram, statistics and a uniformity test on the draw, then copy or download as text, JSON, CSV, one-per-line, a JavaScript or Python literal, or SQL VALUES.
- 05For a draw someone else has to trust, use Provable draw: commit, publish the hash, then draw and publish the record. Copy settings link shares the form, never the numbers.
Four draws people actually run
Raffle or giveaway winners
250 entries, three prizes, nobody wins twice, two disqualified. Unique mode draws without replacement; a provable draw makes it auditable.
Range: 1–250 How many: 3 No repeats: on Exclude: 44, 91
17, 108, 233
Tabletop dice without the dice
A d20 at the kitchen table, or 4d6kh3 for a character stat — keep/drop, exploding dice and multi-term expressions.
4d6kh3
4d6kh3 [6 5 (2) 4] = 15
Random sample for testing or QA
Spot-check 25 rows of a 10,000-row export. Unique and sorted gives an audit-friendly picklist; the SQL or Python export drops into a script.
Range: 1–10000 How many: 25 No repeats: on · Sort: on Export: Python list
random_numbers = [112, 486, 1204, …]
Load-test data with a realistic shape
Response times are not uniform. Draw 5,000 log-normal values, then check the histogram before committing the fixture.
Range: 1–2000 How many: 5000 Distribution: Log-normal Log mean: 5 · Log SD: 0.6
148, 96, 213, 402, …
Ranges people draw from, and what to type
| You want | Range | Settings |
|---|---|---|
| Coin flip | 0–1 | 1 number — 0 heads, 1 tails |
| Die roll (d6) | 1–6 | Dice preset; set “How many” to 2 for 2d6 |
| D20 / RPG dice | 1–20 | D20 preset, or the dice panel for 2d20kl1 |
| Pick a number 1–10 | 1–10 | Preset; the everyday “pick a number” case |
| Percent / 1–100 | 1–100 | Preset and the default range |
| Lottery-style line | 1–49 | Lotto preset: 6 numbers, no repeats, sorted |
| Raffle winners | 1–entries | “How many” = number of prizes, No repeats on, disqualified entries in Exclude |
| Sample of a dataset | 1–row count | No repeats + sort + one-per-line export, paste as a picklist |
| Test decimals | any | Decimals mode, places to match your data (2 for money-like values) |
| Negative or mixed-sign range | −50 to 50 | Type either bound negative; the parity filter handles negatives too |
| Huge integers (keys, IDs) | up to 308 digits | Integer mode draws with BigInt arithmetic — exact, never rounded |
Distribution shapes, and the data each one fits
| Distribution | Parameters | Shape | Typical use |
|---|---|---|---|
| Uniform | none | Every value equally likely | Draws, dice, sampling — the only mode where “No repeats” applies |
| Normal (Gaussian) | mean, std dev | Symmetric bell | Measurement noise, heights, scores around an average |
| Log-normal | log mean μ, log SD σ | Right-skewed, positive only | Durations, response times, incomes — long right tail |
| Exponential | rate λ | Decaying from the low end | Gaps between independent events |
| Poisson | lambda λ | Discrete counts around λ | Arrivals per interval, defects per batch |
| Binomial | trials n, probability p | Discrete successes out of n | Conversions out of n visitors, heads in n flips |
| Triangular | min, mode, max | Peak at the mode, linear sides | Rough estimates with a best guess and hard limits |
All seven draw from the same CSPRNG as the uniform path; values outside your range are redrawn rather than clamped, so no probability mass piles up on the endpoints.
How this compares to a true random number generator
| Source | What it is | Predictable? | Right for |
|---|---|---|---|
Math.random() | Fast in-browser pseudo-random formula | Yes — output can be reconstructed from observed values | Animations, game feel, anything where fairness is cosmetic |
crypto.getRandomValues (this tool) | CSPRNG, continuously reseeded from OS hardware entropy | Not in any practical sense | Draws, sampling, shuffles, test data — any fairness-sensitive pick |
| Seeded PRNG (this tool, opt-in) | SFC32 seeded by hashing your seed text | Yes, by design — anyone with the seed reproduces it | Reproducible fixtures, audits, published draws |
| Atmospheric noise (random.org) | Physical radio noise, digitized server-side | No — physically nondeterministic | Research needing an auditable physical source; comes with quotas and a network trip |
| Physical dice / lottery machine | Mechanical randomness | No, but slow and unaudited at home | Casual play, teaching, ceremony |
“Truly random” properly describes physical sources; a CSPRNG is deterministic machinery reseeded by physical entropy. Honest tools say which they are instead of blurring the two — and a seeded draw is reproducible on purpose, which is a feature for audits and a disaster for secrets.
Where random draws go wrong
Modulo bias in home-rolled generators
Mapping a raw random word onto a range with a bare % biases low values whenever the range does not divide the word’s span evenly — tiny at range 6 over 2³², real at larger ranges. Rejection-sample instead, in the mapping and the shuffle, and be suspicious of any “provably fair” pseudocode that reduces a seed with % (i + 1).
Math.random() is not for anything that matters
Its state can be recovered from observed output, so draws, prizes, tokens and shuffles with stakes need a CSPRNG — weighted draws included. Keep it for confetti. A number drawn here is fair, not secret: anything that has to stay unguessable afterwards is a job for the password generator, which draws from the same source and never shows the result to anyone else.
Drawing without repeats, and when the range runs out
Ten unique values from 1–10 is a full permutation; eleven is impossible and errors. Parity and exclusions shrink the pool too — 1–10 holds five odd values, so six unique odd numbers cannot exist. The error names what remains.
A commitment published after the draw proves nothing
Commit–reveal only fixes the order of two events. Draw first, publish the commitment afterwards, and you could have drawn a hundred times and kept the result you liked. Publish the hash somewhere timestamped before pressing Draw.
Random looks streaky — that’s the point
Uniform draws cluster: the same number twice running, three evens in a row, a tight bunch of values. Humans read streaks as broken, statistics reads them as expected, and the runs test says which it is — too few runs (sorted-looking) or too many (over-alternating) is the suspicious result. One test in twenty fails at p=0.05 on good numbers.
No browser RNG is lottery-grade
Regulated lotteries run on certified hardware generators with audit trails. This tool is fair, unpredictable and verifiable after the fact — fine for raffles, classrooms and games among people who trust each other — but it is not certified for regulated gambling, and no browser tool honestly is.
Entropy source, ranges and caps
- Randomness source
crypto.getRandomValues, the OS-entropy-seeded browser CSPRNG. Opt-in seeded mode: cyrb128 → SFC32, 12 outputs discarded- Range mapping
- Rejection sampling at every size — no modulo reduction anywhere, shuffle included. Spans wider than 2³² take as many 32-bit words as they need and assemble them with BigInt arithmetic, so the span is not capped
- Bounds
- Integers: whole numbers up to 308 digits, negative, positive or mixed-sign, inclusive on both ends, with no cap on the span (maximum − minimum + 1) — so the full ±9,007,199,254,740,991 safe-integer range draws end to end. Decimals: any finite double
- Count
- 1–10,000 values per draw
- Decimals
- 0–9 places, drawn as scaled integers so uniformity and uniqueness carry over exactly
- Unique mode
- Partial Fisher–Yates up to 100,000 values, Set-based rejection above. Uniform draws only
- Parity + exclusions
- Uniform draw over the odd/even progression; excluded values leave the pool, and errors report what remains
- Distributions
- Normal (Box–Muller), log-normal, exponential and triangular (inverse CDF), Poisson (Knuth, λ-splitting), binomial (log-space pmf, binary search) — each truncated to the range by rejection
- Statistics
- Chi-square uniformity (one bin per value, ≤1,000 bins, ≥100 values) and a Wald–Wolfowitz runs test about the median, from a local incomplete gamma implementation
- Provable draw
- SHA-256 (SubtleCrypto) over canonical JSON of {seed, min, max, count, unique, sort, parity, mode, decimals, exclude, toolVersion}; 256-bit seed; replay through the seeded PRNG. Uniform only, so replay is bit-identical on any engine
- Dice notation
- NdM with kh/kl/dh/dl, exploding (!) and multi-term ± expressions; ≤1,000 dice per term, ≤20 terms, ≤1,000,000 sides, ≤100 explosions per die
- Export formats
- Plain, JSON array, CSV, one-per-line, JavaScript array, Python list, SQL VALUES
- Persistence
- Preferences in localStorage; settings-only URL parameters (
?min=1&max=49&n=6&unique=1&sort=1). Results are never stored or serialised - Rendering
- Lists past 1,000 values render in 2,000-value chunks; statistics compute lazily, off the render path
- Offline
- Installable PWA whose service worker caches this tool’s own assets only
- Not this tool’s job
- Identifiers rather than numbers in a range — a v4 or v7 UUID is 122 random bits formatted for collision resistance, not a draw from bounds you choose
- Network
- None from tool code. A test sweep calls every function this page uses with
fetchandXMLHttpRequestreplaced by stubs that throw, so a stray request fails the build instead of shipping. Disconnect from the network and the page still works.