Generate KSUID
A 160-bit identifier encoded as 27 base62 characters — 32 bits of seconds since a 2014 epoch followed by 128 random bits, giving you more entropy than a UUID at the cost of one extra character.
Generated · 0 IDs
Options
This ID
Collision
The 32-bit timestamp separates different seconds. Inside one second, the 128-bit random payload is the collision guard.
Validate and parse KSUID
Paste an ID
About KSUID
Use when: you want even more entropy than UUID v7 or ULID — KSUID adds 32 random bits on top, at the cost of one extra character.
Avoid when: every URL byte matters. ULID is one character shorter and gives you 128 bits, which is already overkill in practice.
How it is generated
A KSUID is 20 raw bytes (160 bits) base62-encoded into exactly 27 characters. The leading 4 bytes are a timestamp; the trailing 16 bytes are pure randomness — twice the entropy of a UUID.
The time field uses a custom KSUID epoch (2014-05-13) and one-second precision. One second is the lookup granularity, but the 128 bits of random tail mean collisions are statistically impossible.
Base62 means the encoded form is case-sensitive (different from base36) and URL-safe.
- 01 Compute Math.floor(Date.now() / 1000) - 1_400_000_000 to get seconds since the KSUID epoch.
- 02 Write that as a 32-bit big-endian integer into bytes 0–3 of a 20-byte buffer.
- 03 Fill bytes 4–19 with 16 random bytes from crypto.getRandomValues.
- 04 Treat the 20-byte buffer as a single 160-bit big-endian unsigned integer and base62-encode it.
- 05 Left-pad the result with the alphabet’s zero character ("0") until it is exactly 27 characters.
Source bytes (20):
byte: 0 1 2 3 | 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
└────┬───┘ └──────────────────────┬──────────────────────┘
│ └── 16 random bytes (128 bits)
└──────────────────────────── 32-bit BE timestamp
seconds since 2014-05-13
Encoded form (27 chars): the 20 bytes are treated as one big-endian
160-bit integer, base62-encoded, then left-padded with "0" so the
output is always exactly 27 characters.
example: 2YjKqGZmZx8sfZWk3PnXYrVqRtL
Alphabet (base62, case-sensitive):
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz All of this runs in your browser. Random bytes come from crypto.getRandomValues, timestamps come from the system clock, and nothing about the generated ID leaves the tab.