How to use this Random Number Generator
Enter a minimum number, maximum number, and the quantity of results you want. Turn on the
unique option if you want non-repeating values. Then click
Generate Numbers to create the result instantly.
- Enter the minimum value.
- Enter the maximum value.
- Choose how many numbers to generate.
- Enable unique-only mode if you do not want duplicates.
- Click Generate Numbers.
Common uses
- Giveaways and lucky draws
- Testing and sample data
- Classroom activities
- Games and quick picks
- Simple simulations and random selection tasks
What this tool can control
- Minimum value
- Maximum value
- Quantity of results
- Optional non-repeating output
- Copy and text download support
These numbers are convenient, not unpredictable
This tool generates numbers with JavaScript's Math.random(), which is exactly
right for what it is used for here: dice rolls, sampling, test fixtures, picking a name from
a hat, casual quick picks. None of that is security-sensitive, so a fast,
convenient generator is the correct tool.
What Math.random() is not is a CSPRNG. It keeps a small internal
state (an xorshift128+ variant in V8, the engine behind Chrome and Node) and
produces a fixed, deterministic stream from it. An observer who collects enough outputs can
recover that state and then predict every future number. So never use these
values where money or security is on the line: real-stakes lotteries, giveaways with prizes
worth gaming, session tokens, API keys, password-reset codes, or shuffling a deck for
gambling. For unpredictable numbers you need crypto.getRandomValues() — the
Password Generator and
Random String Generator use it.
The correct formula for a uniform inclusive range
To pick a uniform integer between min and max where both
endpoints are possible, the correct expression is:
Math.floor(Math.random() * (max - min + 1)) + min
Two mistakes bite people constantly. The first is forgetting the + 1:
write Math.random() * (max - min) and max itself becomes
impossible to hit, quietly turning an inclusive range into a half-open one. The second is
reaching for Math.round() instead of Math.floor() on a scaled
value. Math.round() makes the two endpoints half as likely as
every interior number, because each interior value collects a full unit-wide band of inputs
while the ends only catch a half-width band. The result still looks random but is subtly
non-uniform — the kind of bug that never shows up in a quick eyeball test and quietly skews
a simulation.
Modulo bias, and why flooring sidesteps it
When you map a large set of random values onto n outcomes using the
% (modulo) operator, the distribution skews unless the size of that set is an
exact multiple of n. If it is not, the lower outcomes come up slightly
more often than the higher ones, because they get one extra source value each. On
a die-sized range the effect is tiny, but across many draws — or a large n — it
is measurable.
The Math.random() * n then Math.floor() pattern avoids integer
modulo entirely, so it does not inherit that bias. Floating-point math has its own
microscopic quirks at this scale, but they are negligible for everyday use. When the source
is raw bytes rather than a float — as with a CSPRNG — modulo bias becomes a real problem
that needs rejection sampling to remove; the
Random String Generator page walks through that
in detail.
You cannot seed Math.random() in JavaScript
A surprise for anyone arriving from Python's random.seed() or NumPy:
JavaScript's Math.random() cannot be seeded. There is no API
to fix its starting state, so you cannot reproduce a sequence for a test, replay a bug, or
share a seed with a teammate so they generate the same numbers.
If you need deterministic, reproducible randomness, use a small seedable PRNG that you
control — mulberry32 and sfc32 are popular, compact choices that
take an explicit seed and produce the same stream every time. Be clear about the trade-off,
though: those are still not cryptographically secure. Reproducibility and
unpredictability are opposite goals, so a seedable PRNG is for tests and simulations, never
for secrets.
Why the "+ 1 then floor" pattern lands evenly
Math.random() returns a floating-point number in the half-open interval
[0, 1). That means it can return exactly 0 but never exactly
1. This detail is not trivia — it is the whole reason the standard formula works.
Multiply that [0, 1) value by (max - min + 1) and you get a
number in [0, max - min + 1) — every value from 0 up to, but not
including, max - min + 1. Apply Math.floor() and you land on each
integer from 0 to max - min with equal probability; add
min and every value from min to max inclusive is
equally likely. If Math.random() could ever return 1, the floor
would occasionally produce max + 1 and overshoot the range — which is exactly
why the specification excludes it.
Frequently Asked Questions
Are these numbers safe for a lottery, giveaway, or password?
No, not for anything with real stakes. The numbers come from
Math.random(), a predictable pseudo-random generator whose state can be
recovered from its output. That is fine for casual picks and test data, but for a
real-stakes draw or any secret you need a CSPRNG such as
crypto.getRandomValues().
Is Math.random() cryptographically secure?
No. It is a fast pseudo-random generator (an xorshift128+ variant in V8)
with a small, deterministic internal state. An observer who sees enough outputs can
reconstruct that state and predict every future number, so it is unsuitable for tokens,
keys, or anything that must be unguessable.
How do I get a uniform inclusive range without bias?
Use Math.floor(Math.random() * (max - min + 1)) + min. Do not drop the
+ 1 (that makes max impossible), and do not use
Math.round() on a scaled value — rounding makes the two endpoints half as
likely as the interior numbers, which is a subtle non-uniform distribution.
Can I reproduce the same sequence with a seed?
Not with Math.random() — JavaScript gives no way to seed it, so you cannot
replay a sequence. If you are coming from Python's random.seed() or NumPy and
need reproducibility, use a small seedable PRNG such as mulberry32 or
sfc32. Those are deterministic but still not cryptographically secure.
What is modulo bias?
When you fold a large set of random values onto n outcomes with the
% operator and the set size is not an exact multiple of n, the
lower outcomes appear slightly more often. Flooring a scaled Math.random()
avoids integer modulo and so avoids this skew.
Can Math.random() ever return exactly 1?
No. It returns a float in the half-open interval [0, 1) — it can return
0 but never 1. That is exactly why multiplying by
(max - min + 1) and flooring lands evenly on every integer, including
max, without ever overshooting the range.