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.

Browser extensions can read all data on this page. Use a private/incognito window with extensions disabled.

Generated · 0 IDs

Options

This ID

Length 27 chars
Bits 160 (32 timestamp · 128 random)
Collision risk negligible
Features
Time-sortable URL-safe

Collision

1% collision chance after ≈ 2,615,321,040,553,088,063 IDs
Random part 128 random bits
Counted together Same second

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.

  1. 01 Compute Math.floor(Date.now() / 1000) - 1_400_000_000 to get seconds since the KSUID epoch.
  2. 02 Write that as a 32-bit big-endian integer into bytes 0–3 of a 20-byte buffer.
  3. 03 Fill bytes 4–19 with 16 random bytes from crypto.getRandomValues.
  4. 04 Treat the 20-byte buffer as a single 160-bit big-endian unsigned integer and base62-encode it.
  5. 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.

YouShallNotPass.io

Practical security tools. We never see your secrets. Open source. No accounts. No tracking.

Support YouShallNotPass.io by starring us on GitHub and sharing it with coworkers and friends.

Sister sites

© 2026 YouShallNotPass.io