Random String Generator
Random strings from crypto.getRandomValues with rejection sampling, the entropy in bits, and the collision chance for the batch you asked for.
# 5 strings, 32 characters from 62
# 190.5 bits each
generated-in-your-browser
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
The line most random strings get written as is
Math.random().toString(36).slice(2). It is fast, it is four words long, and it is
the wrong tool for anything that functions as a secret: Math.random is a
pseudo-random generator seeded from whatever the engine felt like, and its future
output is derivable from enough of its past output.
This uses crypto.getRandomValues, and it does the other thing that line gets wrong:
it picks characters by rejection sampling rather than by taking a byte modulo the
alphabet size. 256 does not divide by 62, so the modulo makes the first eight
characters of the alphabet more likely than the rest.
Every string is generated in your browser when the page loads, and the entropy is stated in bits rather than described as secure.
How to use
- Pick the alphabet.
urlsafefor anything going in a path or a query string,base58for anything a human will read out,hexfor identifiers. - Set the length. 22 characters of alphanumeric is 131 bits.
- Add a prefix if you label your tokens, and read the collision figure before you use one as a database key.
Example
Five 32-character alphanumeric strings with an sk_ prefix:
sk_qz6aw2MeC39vWyGLNxkpkz94wj0HbLgL
sk_eRHErI4HbxQcKPBSRb585g1sH5Yf4qpM
sk_ah3pyPyDSIbFctstGk7HpQ3MyuMGMNOA
sk_2hvXqPFmTmpnGyrHGe7GBv62T8WyBHzP
sk_9pKyVXBpVQbgMJqvUgTzsdY3TWQmM2Nm
Alphabet 62 characters (alphanumeric)
Length 32
Entropy each 190.5 bits
Keyspace 2^190.5
Collision chance in this batch under 1 in a trillion
Yours will differ. 190 bits is more than anything needs; 128 is the usual floor for a token that grants access, and at 62 characters that is 22 of them.
Pitfalls
Math.random is not random enough for a secret. It is a PRNG with a hidden seed
and enough structure that its state can be recovered from its output. Use it for test
fixtures and animation jitter. Not for tokens, not for password resets, not for
anything a person should not be able to guess.
A modulo skews the distribution. byte % 62 maps 256 values onto 62, and because
256 = 4 × 62 + 8, the first eight characters get five chances and the rest get four.
On a 32-character string that is a measurable bias, and rejection sampling costs
nothing worth counting.
A prefix is not entropy. sk_live_ is on the front of every one of your keys and
in your documentation. The figures here count the random part only, which is the only
honest way to count them.
Length in characters is not length in bits. Sixteen hex characters is 64 bits and sixteen alphanumeric characters is 95, because the alphabet is larger. Read the bits, not the character count.
Check the collision figure for keys. A random string is safe as a primary key when the chance of drawing the same one twice across the whole table is negligible. At 64 bits and a million rows that chance is about one in thirty-seven million, which is fine. At 32 bits and a million rows a collision is a near certainty, because the chance grows with the square of the row count and eight hex characters is only four billion values.
Client-side generation means the value is in the browser. That is the point here, and it is a reason to be careful: a production secret should be generated where it will live, by the server or the CLI that owns it. This tool is for development keys, test fixtures, seeds and one-off identifiers.
Compatibility
crypto.getRandomValues is in every browser since around 2013, and it is the API
backed by the platform’s own cryptographic random source. Nothing is uploaded and
nothing is stored: the strings exist in your tab and in your clipboard.
The page recomputes on load, so what you see is yours and not the build’s. During the build there is no randomness available, so the compiled default output is a placeholder, which is the only correct thing to bake into a shared page.
Entropy is length × log2(alphabet), which is exact for a uniform draw and is the
only meaningful measure of a random string. The collision figure uses the birthday
approximation, n(n−1)/2 ÷ 2^bits, which is accurate while the probability is small.
urlsafe is the base64url alphabet: A-Z a-z 0-9 - _. It survives a path segment, a
query string, a filename and a header without escaping.
Frequently asked questions
How long should a token be?
Is this better than a UUID?
Why avoid 0, O, I and l?
base58 is for: it drops the four characters that get confused, at the cost of
0.1 bits per character.