Free tool
Random string generator for keys, tokens and IDs
Make random strings from letters, digits, hex, Base58 or your own characters, or encode random bytes as hex or Base64url. Add a prefix like sk_test_, group the characters, and get up to 10,000 unique strings as lines, JSON, CSV or a .env file.
Free · no sign-up · runs in your browser, nothing is uploaded
62 characters, 5.95 bits each
Entropy per string
190.5 bits
Very strong
Length
-
characters, with prefix
Chance of a repeat
< 1e-15
repeats removed
Output appears here.
- Shell
LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32; echo - Python
python3 -c "import secrets, string; a = string.ascii_uppercase + string.ascii_lowercase + string.digits; print(''.join(secrets.choice(a) for _ in range(32)))" - Node.js
node -e "const c = require('crypto'), a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let s = ''; for (let i = 0; i < 32; i++) s += a[c.randomInt(a.length)]; console.log(s)"
Made with crypto.getRandomValues and rejection sampling in this tab. The strings are not sent anywhere and never go in the URL.
Which alphabet and length to pick
Each character from an alphabet of size N carries log2(N) bits. To reach a target strength, divide the bits you need by the bits per character. These are the lengths for 128 and 256 bits:
| Format | Characters | Bits per char | 128 bits | 256 bits |
|---|---|---|---|---|
| Hex | 0-9 a-f | 4 | 32 chars | 64 chars |
| Base64url | A-Z a-z 0-9 - _ | 6 | 22 chars | 43 chars |
| Alphanumeric | A-Z a-z 0-9 | 5.95 | 22 chars | 43 chars |
| Base58 | no 0 O I l | 5.86 | 22 chars | 44 chars |
| Lowercase + digits | a-z 0-9 | 5.17 | 25 chars | 50 chars |
| Crockford Base32 | no I L O U | 5 | 26 chars | 52 chars |
| Digits | 0-9 | 3.32 | 39 chars | 78 chars |
Use hex or Base64url for secrets that only machines read, like webhook signing keys or SESSION_SECRET. Use Base58 or Crockford Base32 for codes people read or type, such as licence keys and coupon codes, since they leave out characters that look alike. Lowercase + digits suits subdomains and other case-insensitive places.
API key formats with prefixes
Many services put a short, readable prefix in front of the random part. Stripe keys start with sk_live_, sk_test_ or pk_live_, so you can tell a secret key from a publishable one and live from test at a glance. GitHub tokens start with ghp_ (personal access token), gho_ (OAuth), ghu_, ghs_ or ghr_, and end with a CRC32 checksum so scanners can reject fake matches without a lookup.
To make keys in that style here:
- Click the API key preset: 32 alphanumeric characters (about 190 bits) after
sk_test_. - Change the prefix to your own, for example
acme_live_. Keep it unique to your product so secret scanners can match it. - Pick .env as the output format to get lines like
API_KEY=…ready to paste.
Store only a hash of each API key on the server (SHA-256 is enough for random keys), and show the full key to the user once.
Random strings in code
Every major language has a secure random source. These match what the tool does:
// Browser JavaScript: 32 random bytes as hex
const bytes = crypto.getRandomValues(new Uint8Array(32));
const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
// Node.js
const { randomBytes, randomInt } = require('node:crypto');
randomBytes(32).toString('base64url'); // 43 chars, 256 bits
const a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
Array.from({ length: 32 }, () => a[randomInt(a.length)]).join('');
# Python
import secrets, string
secrets.token_hex(32) # 64 hex chars
secrets.token_urlsafe(32) # 43 Base64url chars
''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(32))
// Go 1.24+
rand.Text() // Base32, at least 128 bits
# Terminal
openssl rand -hex 32
LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32; echoFor identifiers rather than secrets, a UUID or Nano ID is often a better fit. To sign a token with a key you made here, try the JWT generator.
Two mistakes that make random strings weak
Using Math.random(). It is a fast general-purpose generator, not a cryptographic one, and its future output can be worked out from past output. Fine for shuffling a demo list, wrong for anything secret.
Modulo bias. The common shortcut alphabet[byte % 62] is uneven: 256 = 4 × 62 + 8, so the first 8 characters of the alphabet come up 5 times in 256 and the rest only 4. Over many strings that is measurable and lowers the real entropy. This tool uses rejection sampling: it draws a 32-bit number, throws it away if it falls in the uneven tail, and draws again. The tr -dc command above is unbiased for the same reason, since it simply drops bytes outside the set.
Need a password a person will type rather than a token? The password generator has passphrases, look-alike filtering and a crack-time estimate. For products that manage secrets for you, see security tools on DevHunt.
More free developer tools
FAQ
How do I generate a random string?+
Pick an alphabet and a length above, and the strings appear at once. In code, use your language's secure random source: secrets.token_urlsafe() in Python, crypto.randomBytes() in Node.js, crypto/rand in Go, or openssl rand -hex 32 in a terminal. The panel under the output shows the matching command for your settings.
Are these random strings secure enough for API keys and secrets?+
Yes. They come from crypto.getRandomValues, the browser's cryptographically secure generator, with rejection sampling so no character is more likely than another. They are made in your tab and never sent or put in the URL. Use at least 128 bits of entropy for anything that must not be guessed.
How long should a random token be?+
128 bits is a common floor for secrets, which is 32 hex characters or 22 Base64url or alphanumeric characters. Python's secrets docs suggest 32 bytes (256 bits) for typical use, which is 64 hex characters or 43 Base64url characters. The entropy stat above shows the bits for your settings.
What is the difference between hex, Base64 and Base64url?+
They are ways to write random bytes as text. Hex uses 0-9 and a-f, 2 characters per byte. Base64 uses A-Z, a-z, 0-9, + and /, about 1.33 characters per byte, with = padding. Base64url swaps + and / for - and _ and drops the padding, so it is safe in URLs, file names and cookies.
Can two random strings be the same?+
Yes, by chance, and the odds grow with the square of how many you make (the birthday problem). The tool shows the chance of a repeat for your batch. With "No duplicates" on, repeats are removed and replaced. At 128 bits, even billions of strings have a vanishingly small chance of a repeat.
Why do API keys start with a prefix like sk_live_?+
A prefix tells people and scanners what the key is. Stripe uses sk_live_ and sk_test_ so a live key is easy to spot, and GitHub uses ghp_ and similar prefixes so its secret scanning can find leaked tokens with few false positives. Add your own prefix in the Prefix box; it does not add entropy.
Is Math.random() OK for random strings?+
Only for things that do not need to be secret, like test data or a CSS class name. Math.random() is not cryptographically secure and its output can be predicted. For tokens, session IDs, invite codes or keys, use crypto.getRandomValues() in the browser or crypto.randomBytes() in Node.js.
Sources: MDN: crypto.getRandomValues() · Python secrets · Node.js crypto.randomBytes · Go crypto/rand · RFC 4648 (Base16, Base32, Base64) · Crockford Base32 · GitHub token formats · Stripe API keys. Checked 2026-10-31.