UUID v5 Generator
UUID v5 is the SHA-1 cousin of v3. Same input always yields the same UUID. Prefer v5 for new code.
Show all 0
v5 in one paragraph
Take a namespace UUID (16 bytes), append the UTF-8 bytes of a name, SHA-1 the result, take the first 16 bytes, set the version (5) and variant bits. Done. The output is fully deterministic, so any system given the same namespace and name produces the same UUID.
When v5 shines
- Cross-service IDs. Service A and service B both compute the same UUID for "
order:abc123" without having to share a database. - Idempotent imports. Re-running an import job produces the same UUIDs; you can use upsert by primary key.
- Test fixtures. Deterministic UUIDs make snapshot tests stable.
v5 in code
// JavaScript / TypeScript
import { v5 } from "uuid";
const NS = v5.URL; // 6ba7b811-9d1d-11d1-80b4-00c04fd430c8
v5("https://example.com/users/42", NS);
// Python
import uuid
uuid.uuid5(uuid.NAMESPACE_URL, "https://example.com/users/42")
// Go
import "github.com/google/uuid"
uuid.NewSHA1(uuid.NameSpaceURL, []byte("https://example.com/users/42"))
// PostgreSQL (with uuid-ossp extension)
SELECT uuid_generate_v5(uuid_ns_url(), 'https://example.com/users/42'); Choosing your own namespace
For internal use, generate one v4 UUID and hard-code it as the namespace for your project. Every entity type derived from this namespace then has its own deterministic UUID space, isolated from other projects.
// One-time: generate this once and commit as a constant
const ORDERS_NS = "8a4c2d6e-1f3b-4a5c-9d8e-7f6a5b4c3d2e";
// Forever: same input → same UUID
v5(`order:${orderId}`, ORDERS_NS);
v5(`shipment:${shipmentId}`, ORDERS_NS); Common pitfalls
- Encoding inconsistency. v5 hashes the UTF-8 bytes of the name. If you compute v5 in JavaScript with
"café"and in Python with the same string, the bytes are identical (UTF-8). But if a library somewhere passes UTF-16 bytes, you'll get a different UUID. Always serialize names to UTF-8 explicitly. - Trailing whitespace.
"example.com"and"example.com "hash to different UUIDs. Trim before hashing. - Case sensitivity.
"Example.com"and"example.com"are different inputs. Lowercase first if you want case-insensitive identity. - Don't use as security tokens. SHA-1 has known collision attacks (SHAttered, 2017). v5 is for identity derivation, not signatures.
Real-world use cases
- Stable IDs from external keys. Importing data from a vendor that uses string IDs?
v5(vendorId, NS_VENDOR)gives you a UUID that's the same on every re-import, so upserts work without a separate mapping table. - Cross-service identity. Two microservices can both compute the v5 UUID for "
user:alice@example.com" without coordinating, and they'll arrive at the same value. - Idempotent webhook handlers. Use the webhook event ID + your service namespace to derive a UUID. Re-delivery of the same event gives you the same UUID; you can use it as the primary key with
ON CONFLICT DO NOTHING.
FAQ
Why use v5 instead of v3?
v5 uses SHA-1 instead of MD5. SHA-1 is faster on modern hardware, has better collision properties (for non-adversarial inputs), and is the recommended choice for new deterministic UUID generation.
Same name, different namespace — different UUID?
Yes. The whole point of namespaces is that v5(NS_DNS, 'example.com') and v5(NS_URL, 'example.com') are different UUIDs.
Can I use v5 to deduplicate records?
Yes — that's a great use case. Hash a stable identity (e.g. lowercase email, or a normalized URL) into a v5 UUID and use it as the primary key. Two systems can independently arrive at the same UUID without coordination.
Is v5 cryptographically secure?
No. SHA-1 is broken for adversarial collision resistance. Don't use v5 to derive keys, signatures, or anti-tamper IDs. It's purely an identifier-derivation tool.