Crypto math ·
The anatomy of a UUID: collision math and CSPRNG v4 generation
A version-4 UUID is 128 bits with version and variant bits overwritten, leaving 122 random bits from a CSPRNG. Birthday-bound collisions are negligible for normal app volumes and irrelevant compared to bugs that reuse Math.random. Generate v4 in the tab. Do not treat the string as an API secret.
Layout and 122 random bits
Set version nibble to 4, variant to RFC 4122/9562 (10xx). Remaining bits: getRandomValues into 16 bytes.
const b = new Uint8Array(16);
crypto.getRandomValues(b);
b[6] = (b[6] & 0x0f) | 0x40;
b[8] = (b[8] & 0x3f) | 0x80;Birthday bound
P ≈ n² / 2k with k = 2^122. Spreadsheets that scare you with “UUID collisions” usually assume 128 bits without version bits or assume a PRNG.
CSPRNG versus Math.random
Same lecture as password generation. Libraries that use Math.random for UUIDs are defects.
Formatting
8-4-4-4-12 hex. Lowercase is canonical in many stacks. Do not insert extra entropy by “shuffling” hex; you would break version bits.
Not a secret
UUIDs appear in URLs and logs. Access control must not be “knows the UUID.” Pair with real auth (JWT article) when the object is sensitive.
Frequently asked questions
How many v4 UUIDs before a collision is likely?
On the order of 2^61 generated IDs for ~50% collision probability (birthday bound on 122 bits). That is not your bottleneck.
Is uuid v4 a good session token?
It is guessable relative to a 256-bit token if the CSPRNG is broken, and it is logged everywhere. Use a dedicated token length. Entropy article applies.
What about UUID v7?
Time-ordered. Better for indexes, different privacy tradeoff (leaks time). This article generates v4.