Why this matters
The built-in `Math.random()` function in JavaScript is deliberately not cryptographically secure. Its output is deterministic enough that, in some browser implementations, observing a sequence of outputs can allow an attacker to predict future values. For security-sensitive applications like generating OTP codes, lottery draws, or cryptographic nonces, this predictability is a serious vulnerability. The Web Crypto API's `crypto.getRandomValues()` function provides access to the operating system's cryptographic random number generator, which uses hardware entropy sources that are fundamentally unpredictable.
Beyond security, the tool implements rejection sampling to eliminate modular bias. When you ask for a random number between 1 and 7 using a byte (0-255), simply taking the modulo 7 introduces a slight bias because 256 is not evenly divisible by 7. Rejection sampling discards the out-of-range values and retries, producing a perfectly uniform distribution. The unique-draw mode uses a Fisher-Yates shuffle to guarantee no duplicates, which is essential for raffles, randomised assignments, and sampling without replacement.
Feature comparison
| Feature | Detail |
|---|---|
| Randomness source | crypto.getRandomValues (OS CSPRNG) |
| Bias elimination | Rejection sampling on modular range |
| Unique draws | Fisher-Yates shuffle |
| Max per generation | 10,000 numbers |
| Range | Min and max inclusive |
| Export | Copy to clipboard or download as .txt |
How to use it
Set the minimum and maximum values for your desired range — both endpoints are inclusive.
Choose how many numbers you want to generate, from 1 up to 10,000.
Toggle the Unique option if you need each number to appear at most once (the range must be at least as large as the count).
Click Generate to produce the numbers, then copy them to clipboard or download as a text file.
Testing your result
Generate a large batch of numbers (say 1,000 values between 1 and 100) and copy them into a spreadsheet. Create a frequency distribution to verify that each number appears roughly 10 times with no systematic skew. For unique mode, generate a set where the count equals the range size (for example, 10 numbers from 1 to 10) and verify that every integer in the range appears exactly once. These tests confirm both uniformity and the uniqueness constraint.
Common mistakes
Setting a unique-draw count larger than the range, which is impossible since you cannot draw 50 unique numbers from a range of 1 to 10.
Confusing inclusive and exclusive ranges — this tool treats both min and max as inclusive, so a range of 1 to 6 can produce 6.
Using this for Monte Carlo simulations that need millions of values; the 10,000-per-click cap makes it impractical for high-volume scientific computing.
Assuming the output is truly random rather than cryptographically random — the distinction matters for statistical modelling but not for security.
Edge cases and options
The tool handles any integer range that fits within JavaScript's safe integer limits. When unique mode is enabled, the Fisher-Yates shuffle is applied to an array representing the full range, and the first N elements are returned. This guarantees perfect uniformity among unique draws with zero collision risk. Rejection sampling adds a small and unpredictable overhead for ranges that do not align with power-of-two boundaries, but for typical ranges like 1 to 100 or 1 to 1000 the practical impact is negligible.
Real-world use cases
Generating one-time passwords or verification codes for two-factor authentication systems.
Running raffles or giveaways where each participant must receive a unique number.
Randomising the order of presentation in A/B testing or survey experiments.
Creating test datasets with randomised IDs or values for software development and QA.
Frequently asked questions
Q: Why use crypto.getRandomValues instead of Math.random?
A: Math.random is not cryptographically secure and can have predictable output. crypto.getRandomValues uses the OS CSPRNG, and rejection sampling removes modular bias.
Q: What does the unique toggle do?
A: Each number appears at most once, equivalent to a Fisher-Yates shuffle of the range. The range must be at least as large as the count requested.
Q: Is there a limit on how many numbers I can generate?
A: Up to 10,000 numbers per generation. Unique mode additionally requires the range to be at least as large as the count.
Q: How does rejection sampling work?
A: Instead of taking modulo (which introduces bias when the range does not divide evenly into the random space), invalid values are discarded and new random values are drawn until a valid one appears.
Q: Can I use fractional ranges?
A: No, the tool generates integers only. For fractional results, generate integers and divide by a power of 10 in your downstream code.
Q: Are the generated numbers uploaded anywhere?
A: No. All generation happens on your device with no network activity.
Start using it now
Try the Random Number Generator tool. See also UUID Generator, Username Generator, and Hash Generator.