Developer Tools· 4 min read

Cryptographically Secure Random Number Generator with Unique Draws

Generate unbiased random integers using crypto.getRandomValues with rejection sampling, supporting unique draws and bulk output up to 10,000 numbers.

By EasyDevTools Team Last updated: 2026-08-24

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.

See it in action

Feature comparison

FeatureDetail
Randomness sourcecrypto.getRandomValues (OS CSPRNG)
Bias eliminationRejection sampling on modular range
Unique drawsFisher-Yates shuffle
Max per generation10,000 numbers
RangeMin and max inclusive
ExportCopy 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.

Need help using this tool?

Read our complete Random Number Generator tutorial for step-by-step guidance.

Ready to try the tool?

No accounts. No uploads. No limits. Start now.