Test fixtures need a batch of numbers, debugging needs an identifier that ties requests together across services, and a layout check needs a meaningless run of characters. All three get called "random", yet they demand wildly different things from the randomness. This tool splits them into three tabs: integers, UUIDs, and strings. The important part is that those tabs do not share one source of randomness, nothing on screen says so, and the difference decides what each tab's output may safely be used for.
How to use it
- Three tabs run across the top: "Integer", "UUID" and "String". The middle tab is labelled
UUIDin both the English and Chinese interfaces. - The Integer tab offers "Minimum", "Maximum" and "Count (1–100)" number fields plus a "Generate" button. Results appear one per line below, and the copy button on the "Result" row lifts the whole batch at once, newline separated.
- The UUID tab is a single "Generate UUID" button. It produces one value at a time and each press replaces the previous one. There is no count field and no version selector.
- The String tab has "Length" and "Count (1–100)" number fields plus four character-set checkboxes: "Digits (0-9)", "Lowercase (a-z)", "Uppercase (A-Z)" and "Symbols". The first three are ticked by default, with length 16 and count 5. Adjust them, then press "Generate".
- Nothing generates on its own — no button press, no output. Each tab keeps its own results while you switch between them, but a page reload clears all three.
When it comes in handy
Build a batch of fixtures
A hundred order totals, a column of ages, a shuffled set of priorities to exercise your sort — set the bounds on the Integer tab and press once. What comes out is plain newline-separated numbers, which drop cleanly into a spreadsheet column, a SQL VALUES list, or an array in a test file.
Get an identifier that will not collide
A correlation ID for tracing a request through your logs, an idempotency key that stops a payment being charged twice, a key in an integration test that must not clash with seeded data — one press on the UUID tab and you have a standard-format value, without opening a terminal to run uuidgen.
Stress a field or a layout with placeholder text
Does a 64-character display name break the card layout? Does the VARCHAR(50) column truncate without saying so? Is text-overflow actually taking effect? Set the length to your target, the count to five, and you get strings with no meaning and no spaces in them — ideal for watching pure layout behaviour.
Draw lots, split groups, sample at random
Pull 20 record numbers out of a list of 250 for manual review, pick which files get code reviewed today, split twenty people into four teams. Set the range and the count, press once. Just remember that it samples with replacement, so duplicates are yours to handle — see the note below.
Limits and behavior
- The three tabs draw on two different sources of randomness, and the interface never mentions it. The UUID tab calls the browser's built-in
crypto.randomUUID, while Integer and String both go throughMath.random. The practical consequence is blunt: what the String tab produces must not become a password, an API key, a session token, or the code inside a password-reset link. Math.randomis not broken randomness — it is randomness built for a different goal: fast, well distributed, and under no obligation to hide its internal state. The xorshift128+ generator currently used by Chrome and Node keeps only 128 bits of state. Observe enough output and that state can be solved for, after which every value before and after it falls out. An attacker who sees your first issued token has a real path to the next ones.- The UUID tab deserves a precise statement rather than a flattering one. The code checks whether
crypto.randomUUIDexists and calls it only if it does; otherwise it assembles a correctly shaped v4 string out ofMath.random. That fallback is unreachable in practice here — the site forces HTTPS, andcrypto.randomUUIDhas shipped in secure contexts since Chrome 92, Firefox 95 and Safari 15.4. So the accurate claim is "cryptographically sourced on any supported browser", not an unconditional guarantee. - The entropy figure for strings is a ceiling, not a delivery. The three default sets combine into 62 characters, so a 16-character string is worth roughly 95 bits in theory; tick all four and 88 characters gets you about 103. Underneath, though,
Math.randomcarries 128 bits of state and the strings in one batch are not independent of each other, so genuine unpredictability falls well short of those numbers. Treat the output as convincingly scrambled filler, not as a 103-bit secret. - Ticking a character set does not guarantee at least one character from it. The ticks simply concatenate the pools into one, and each position is then drawn independently. With the defaults — 62 characters, length 16 — about 6% of generated strings contain no digit at all, and with all four sets ticked around 0.4% contain no symbol. If the receiving system insists on a digit and a symbol, expect part of each batch to be rejected and to have to pick through it.
- Integers are sampled with replacement, so they repeat. Each draw is independent; numbers are not removed from a hat. Run the defaults — ten draws from 1 to 100 — and roughly 37% of the time at least one number appears twice. That is the birthday problem doing its job, not a bug.
- Clamping happens at the moment you press the button, and it only touches the value used for the calculation. Count is clamped to 1–100 and Length to 1–256, but the number in the input box is left alone. Type 1000 into Length, press Generate, and you get five strings of 256 characters while the field still reads 1000. One further quirk: entering
0for Length yields 8, not 1, because the code treats0as "nothing entered" and substitutes its default. - All four numeric fields are parsed as integers, and fractions are truncated without comment:
5.9becomes 5,2.99becomes 2. The arrow keys never produce a fraction, but typing or pasting one does. - If pressing Generate does nothing at all, it is almost always one of three things: the minimum exceeds the maximum, one of the numeric fields is empty, or not a single character set is ticked. Each of these stops the calculation before it starts, with no error message, so the button simply looks dead. Check those three and you will usually have your answer.
- The integer draw is a random fraction multiplied by (maximum minus minimum plus one), floored, then offset by the minimum — so both endpoints are included. Once the span exceeds 2^53 the gaps between representable doubles grow past 1 and whole bands of values become unreachable. Irrelevant at everyday ranges, disqualifying if you were hoping to mint 64-bit random IDs here.
- Every value is computed in your browser as you press the button; not one bit is requested from a server, and no result is transmitted or logged. The flip side is that nothing survives navigating away, so copy before you leave. The page itself still loads third-party resources such as advertising, entirely separate from the values you generate.
Frequently asked questions
Which UUID version is this, and can I use it as a database primary key?
Version 4, the fully random one: 6 of the 128 bits are fixed to mark the version and variant, leaving 122 random bits, which makes collisions negligible at any realistic scale. Functionally it works fine as a key, but watch write performance — v4 carries no time ordering, so consecutive inserts scatter across the B-tree, splitting pages and hurting cache locality. Large tables usually move to a time-prefixed UUIDv7 or a ULID instead, and this tool produces neither.
Can I generate 50 UUIDs at once?
No. The UUID tab is one button producing one value, and each press overwrites the last — there is no count field and no accumulating list. On this page the only route to a batch is press, copy, repeat; for real volume, loop over uuidgen or an equivalent in your shell. The Integer and String tabs are the ones with a count field, capped at 100.
I need an API key. Is the String tab good enough?
It is not. Real keys should come from the operating system's cryptographic source: openssl rand -hex 32 in a shell, or crypto.getRandomValues in the browser and Node, secrets.token_urlsafe in Python, crypto/rand in Go. Those read from the OS entropy pool, whose state an observer cannot reconstruct. For your own account passwords, a password manager generating and storing them remains both the easiest and the safest option.
If two people open this page at once, will they get the same values?
No. Each tab's generator is seeded independently by the engine, so two machines — or even two tabs on one machine — produce different sequences. But "will not collide" and "cannot be predicted" are separate properties: the first holding says nothing about the second, and security depends on the second.
Why does the same number appear twice in my results?
Because each draw is independent and nothing is removed from the pool. The narrower the range and the larger the count, the more obvious it gets: ask for 20 numbers between 1 and 10 and repeats are guaranteed by the pigeonhole principle. Getting a distinct list normally means enumerating the whole range, shuffling, and taking the first N — a mode this tool does not have, so deduplicate in a spreadsheet and top up.
Exactly which characters are in the "Symbols" set, and will they break my code?
Twenty-six of them: !@#$%^&*()-_=+[]{}|;:,.<>?. That includes <, > and &, so escape the output before dropping it into HTML or an XML attribute. The set deliberately excludes single quotes, double quotes, backslash, space and forward slash, which is why generated strings usually survive being pasted into a JSON string. $, !, | and & still mean something to a shell, though, so wrap the value in single quotes when passing it as an argument.