UUIDs are everywhere — but their default string format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
) takes up 36 characters, which can be verbose in URLs, QR codes, and user-facing identifiers.
So… what if we could make them shorter — say, 22 characters — while keeping them globally unique?
Good news: we can.
Let’s explore how to safely compress UUIDs using Base64 URL-safe encoding, and when (and how) you should use them.
📏 Why Are UUIDs 36 Characters Long?
The canonical UUID string format looks like this:
550e8400-e29b-41d4-a716-446655440000
- It contains 32 hex characters
- Plus 4 hyphens
- Total: 36 characters
Internally, a UUID is actually 128 bits (or 16 bytes). The string version is just one possible representation.
🎯 Our Goal: 22 Characters
Using Base64 encoding, we can take that 16-byte binary and convert it to a much more compact form.
- Base64 encodes 3 bytes into 4 characters
- 16 bytes → 22 characters + 2 padding
=
We’ll use Base64 URL-safe mode (with -
and _
instead of +
and /
).
By stripping the padding, we get a compact, safe, and unique 22-character string.
🧪 Encoding Example in Python
import uuid
import base64
def uuid_to_short(uuid_obj):
return base64.urlsafe_b64encode(uuid_obj.bytes).rstrip(b'=').decode('ascii')
def short_to_uuid(short_str):
padded = short_str + '=='
return uuid.UUID(bytes=base64.urlsafe_b64decode(padded))
# Example usage
u = uuid.uuid4()
short = uuid_to_short(u)
print("UUID:", u)
print("Short:", short)
# Reverse it
original = short_to_uuid(short)
print("Recovered UUID:", original)
📦 Go (Golang) Example
package main
import (
"encoding/base64"
"fmt"
"github.com/google/uuid"
"strings"
)
func main() {
u := uuid.New()
encoded := base64.URLEncoding.EncodeToString(u[:])
short := strings.TrimRight(encoded, "=")
fmt.Println("Short UUID:", short)
// Decode back
padded := short + strings.Repeat("=", (4 - len(short)%4) % 4)
decoded, _ := base64.URLEncoding.DecodeString(padded)
recovered, _ := uuid.FromBytes(decoded)
fmt.Println("Recovered UUID:", recovered)
}
🧑💻 JavaScript (Node.js) Example
const { v4: uuidv4, parse, stringify } = require('uuid');
function uuidToShort(u) {
const bytes = parse(u);
const base64 = Buffer.from(bytes).toString('base64url');
return base64;
}
function shortToUuid(s) {
const padded = s.padEnd(24, '=');
const bytes = Buffer.from(padded, 'base64url');
return stringify(bytes);
}
const u = uuidv4();
const short = uuidToShort(u);
const recovered = shortToUuid(short);
console.log("UUID:", u);
console.log("Short:", short);
console.log("Recovered:", recovered);
🧠 Why This Works
- UUIDs are exactly 128 bits
- Base64 encoding is deterministic and reversible
- The URL-safe variant replaces
+
with-
and/
with_
- Padding
==
can be dropped safely and restored when decoding
This means we can safely convert UUIDs to shorter, more portable strings.
🛡️ Is It Still Unique?
Yes!
- No entropy is lost — you’re encoding the full 16-byte UUID
- It’s just a different representation, like
hex()
vs.bytes
- UUID collisions remain astronomically unlikely (~1 in 2^122)
🔐 Security and Safety Considerations
- These short UUIDs are not encrypted or obfuscated
- Anyone can decode them back to the full UUID
- Do not embed sensitive data (use JWTs or signed tokens for that)
If you need cryptographic integrity, consider:
- JWTs with claims
- Signed UUIDs (e.g. HMAC(uuid))
- UUIDv5 with secret namespace
📘 Use Cases
- Short URLs (
example.com/r/22charid
) - URL-safe file names
- Embed in QR codes or slugs
- Compact API keys or tokens
- Visual UIs where UUIDs are user-facing
🚫 Don’t Do This
- Don’t truncate UUIDs manually (e.g.
uuid[:8]
) — it destroys uniqueness - Don’t use regular Base64 with
+
and/
in URLs — not safe! - Don’t forget to add padding back when decoding (some libs fail silently)
🧪 Benchmarking Storage and Display
Format | Length | URL-safe | Readable |
---|---|---|---|
UUIDv4 (canonical) | 36 | ❌ | ✅ |
UUID (hex only) | 32 | ✅ | ✅ |
Base64 (URL-safe) | 22 | ✅ | ✅ |
Base58 (optional) | ~22 | ✅ | ✅ |
🔄 Round Trip Consistency
Always test:
UUID → compressed → decompressed → UUID
If you end up with a different UUID at the end, your encoding logic is broken. Stick to well-tested libraries and watch for issues with padding, bytes vs strings, or endianness.
Final Thoughts
If you want shorter UUIDs without losing any uniqueness, Base64 URL-safe encoding is a fantastic solution.
You get:
- Compact 22-character identifiers
- Perfect reversibility
- Full UUID compatibility
- Safe usage in URLs, HTML, filenames, and API paths
So go ahead — compress those UUIDs. Your URLs (and your users) will thank you.
📦 36 → 22: Done right.