UUID Generator
Generate Universally Unique Identifiers (UUIDs) in various versions for unique identification
UUID Generator
Generate Universally Unique Identifiers (UUIDs) in various versions for unique identification
UUID Generation Settings
🕒 Time-based UUIDs
🎲 Random UUIDs
🔐 Hash-based UUIDs
🔤 UUID Best Practices
- • Default Choice: Use UUID v4 for most applications - it's secure and widely supported
- • Database Keys: Consider using sequential UUIDs (v1) for better index performance
- • Deterministic IDs: Use v5 when you need consistent UUIDs from the same input
- • Storage: Store as binary (16 bytes) rather than string (36 chars) when possible
- • Validation: Always validate UUID format when receiving from external sources
About UUID (Universally Unique Identifier)
UUID (Universally Unique Identifier) is a 128-bit standardized identifier format defined by RFC 4122. UUIDs are designed to be unique across space and time without requiring a central authority, making them perfect for distributed systems, databases, and applications requiring unique identification.
- 128-bit (16-byte) standardized format with global uniqueness
- Multiple versions (v1, v4, v5) for different use cases and requirements
- Widely supported across programming languages and databases
- RFC 4122 compliance ensuring interoperability and standards
- No central authority needed for generation and collision avoidance
UUID Versions and Types
Time-Based UUIDs
- Version 1: MAC address + timestamp based
- Version 6: Reordered v1 for better sorting
- Version 7: Unix timestamp + random data
- Pros: Sortable, contains creation time
- Cons: May leak MAC address or time info
- Use cases: Audit trails, event sourcing
Random & Hash-Based UUIDs
- Version 4: Purely random/pseudo-random
- Version 3: MD5 hash-based (deprecated)
- Version 5: SHA-1 hash-based
- Pros: No information leakage, very secure
- Cons: No inherent ordering or time info
- Use cases: General purpose, API keys
Advertisement
Frequently Asked Questions
Which UUID version should I use?
For most applications, use UUID v4 (random) as it's secure, widely supported, and doesn't leak information. Use v1 if you need time-based sorting or v5 if you need deterministic UUIDs from the same input. Avoid v3 as MD5 is deprecated.
Are UUIDs truly unique across all systems?
Yes, when generated properly. UUID v4 has a collision probability so low it's negligible (about 1 in 5.3×10^36). Time-based UUIDs (v1) include MAC addresses and timestamps, making collisions virtually impossible when generated on different machines.
Can UUIDs be used as database primary keys?
Yes, but consider the trade-offs. UUIDs provide excellent uniqueness and work well in distributed systems, but they're larger than integers (16 vs 4-8 bytes) and random UUIDs can cause index fragmentation. Use sequential UUIDs (v1, v6, v7) for better database performance.
How do I generate deterministic UUIDs?
Use UUID v5 with SHA-1 hashing. Provide the same namespace UUID and name string to always generate the same UUID. This is useful for creating consistent identifiers from existing data without storing a mapping table.
UUID Structure and Format
Standard Format:
Example UUIDs:
Sponsored Content
UUID Generation Implementation
JavaScript UUID Generator:
class UUIDGenerator {
constructor() {
this.versions = ['1', '4', '5'];
this.namespaces = {
DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8',
OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8',
X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8'
};
// State for v1 generation
this.clockSeq = Math.floor(Math.random() * 0x4000);
this.lastMSecs = 0;
this.lastNSecs = 0;
this.nodeId = this.generateRandomNodeId();
}
// Generate UUID based on version
generate(version = 4, options = {}) {
try {
const startTime = performance.now();
switch (version.toString()) {
case '1':
return this.generateV1(options);
case '4':
return this.generateV4(options);
case '5':
return this.generateV5(options.namespace, options.name);
default:
return {
success: false,
error: `Unsupported UUID version: ${version}. Supported versions: ${this.versions.join(', ')}`
};
}
} catch (error) {
return {
success: false,
error: error.message
};
}
}
// Generate UUID v1 (time-based with MAC address)
generateV1(options = {}) {
const startTime = performance.now();
// Get timestamp (100-nanosecond intervals since 15 Oct 1582)
const msecs = Date.now();
let nsecs = this.lastNSecs + 1;
// Handle clock regression or same millisecond
if (msecs < this.lastMSecs) {
this.clockSeq = (this.clockSeq + 1) & 0x3fff;
}
if ((msecs === this.lastMSecs) && (nsecs >= 10000)) {
this.clockSeq = (this.clockSeq + 1) & 0x3fff;
nsecs = 0;
}
this.lastMSecs = msecs;
this.lastNSecs = nsecs;
// Convert to UUID timestamp
const timestamp = (msecs * 10000) + nsecs + 0x01B21DD213814000n;
// Build UUID
const timeLow = Number(timestamp & 0xffffffffn);
const timeMid = Number((timestamp >> 32n) & 0xffffn);
const timeHigh = Number((timestamp >> 48n) & 0x0fffn) | 0x1000; // Version 1
const clockSeqHigh = (this.clockSeq >> 8) | 0x80; // Variant
const clockSeqLow = this.clockSeq & 0xff;
const node = options.nodeId || this.nodeId;
const uuid = this.formatUUID([
timeLow,
timeMid,
timeHigh,
clockSeqHigh,
clockSeqLow,
...node
]);
const endTime = performance.now();
return {
success: true,
uuid: uuid,
version: 1,
timestamp: msecs,
clockSequence: this.clockSeq,
nodeId: node,
metadata: {
type: 'time-based',
createdAt: new Date(msecs).toISOString(),
timestampHex: '0x' + timestamp.toString(16),
clockSeqHex: '0x' + this.clockSeq.toString(16).padStart(4, '0')
},
timing: {
duration: Math.round(endTime - startTime),
formatted: `${Math.round(endTime - startTime)}ms`
}
};
}
// Generate UUID v4 (random)
generateV4(options = {}) {
const startTime = performance.now();
// Generate 16 random bytes
const bytes = this.generateRandomBytes(16);
// Set version (4) and variant bits
bytes[6] = (bytes[6] & 0x0f) | 0x40; // Version 4
bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant
const uuid = this.bytesToUUID(bytes);
const endTime = performance.now();
// Calculate randomness entropy
const entropy = 122; // 128 bits - 6 fixed bits
return {
success: true,
uuid: uuid,
version: 4,
bytes: bytes,
metadata: {
type: 'random',
entropy: entropy,
randomnessQuality: 'cryptographically secure',
collisionProbability: '1 in 5.3×10^36'
},
timing: {
duration: Math.round(endTime - startTime),
formatted: `${Math.round(endTime - startTime)}ms`
}
};
}
// Generate UUID v5 (SHA-1 hash-based)
generateV5(namespace, name) {
if (!namespace || !name) {
return {
success: false,
error: 'Both namespace and name are required for UUID v5'
};
}
const startTime = performance.now();
// Resolve namespace if it's a known constant
const nsUuid = this.namespaces[namespace] || namespace;
// Validate namespace UUID
if (!this.validate(nsUuid)) {
return {
success: false,
error: 'Invalid namespace UUID format'
};
}
// Convert namespace UUID to bytes
const nsBytes = this.uuidToBytes(nsUuid);
// Create input for hashing
const nameBytes = new TextEncoder().encode(name);
const input = new Uint8Array(nsBytes.length + nameBytes.length);
input.set(nsBytes);
input.set(nameBytes, nsBytes.length);
// Generate SHA-1 hash
return crypto.subtle.digest('SHA-1', input).then(hashBuffer => {
const hashBytes = new Uint8Array(hashBuffer);
// Take first 16 bytes and set version/variant
const bytes = hashBytes.slice(0, 16);
bytes[6] = (bytes[6] & 0x0f) | 0x50; // Version 5
bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant
const uuid = this.bytesToUUID(bytes);
const endTime = performance.now();
return {
success: true,
uuid: uuid,
version: 5,
namespace: nsUuid,
name: name,
hash: Array.from(hashBytes).map(b => b.toString(16).padStart(2, '0')).join(''),
metadata: {
type: 'hash-based',
algorithm: 'SHA-1',
deterministic: true,
input: `${nsUuid} + "${name}"`
},
timing: {
duration: Math.round(endTime - startTime),
formatted: `${Math.round(endTime - startTime)}ms`
}
};
}).catch(error => ({
success: false,
error: error.message
}));
}
// Generate multiple UUIDs
generateMultiple(count, version = 4, options = {}) {
const results = [];
const startTime = performance.now();
for (let i = 0; i < count; i++) {
const result = this.generate(version, options);
results.push({
index: i + 1,
...result
});
}
const endTime = performance.now();
const successful = results.filter(r => r.success);
return {
success: successful.length > 0,
count: count,
version: version,
successful: successful.length,
failed: count - successful.length,
results: results,
timing: {
total: Math.round(endTime - startTime),
average: successful.length > 0 ? Math.round((endTime - startTime) / successful.length) : 0,
formatted: `${Math.round(endTime - startTime)}ms total`
},
uniqueness: this.checkUniqueness(successful.map(r => r.uuid))
};
}
// Parse UUID into components
parse(uuid) {
try {
if (!uuid || typeof uuid !== 'string') {
return {
success: false,
error: 'UUID must be a non-empty string'
};
}
// Remove hyphens and validate format
const clean = uuid.replace(/-/g, '').toLowerCase();
if (clean.length !== 32 || !/^[0-9a-f]+$/.test(clean)) {
return {
success: false,
error: 'Invalid UUID format'
};
}
// Extract components
const timeLow = clean.substring(0, 8);
const timeMid = clean.substring(8, 12);
const timeHigh = clean.substring(12, 16);
const clockSeq = clean.substring(16, 20);
const node = clean.substring(20, 32);
// Determine version and variant
const version = parseInt(timeHigh[0], 16) >> 0;
const variant = parseInt(clockSeq[0], 16) >> 2;
const formatted = `${timeLow}-${timeMid}-${timeHigh}-${clockSeq}-${node}`;
const analysis = {
uuid: formatted.toUpperCase(),
version: version,
variant: variant,
components: {
timeLow: timeLow,
timeMid: timeMid,
timeHigh: timeHigh,
clockSeq: clockSeq,
node: node
},
bytes: this.uuidToBytes(formatted),
format: 'RFC 4122'
};
// Version-specific parsing
if (version === 1) {
analysis.timestamp = this.parseV1Timestamp(timeLow, timeMid, timeHigh);
analysis.clockSequence = parseInt(clockSeq.substring(1), 16);
analysis.nodeId = node.match(/.{2}/g).map(hex => parseInt(hex, 16));
} else if (version === 4) {
analysis.randomness = 'cryptographically random';
analysis.entropy = 122; // bits
}
return {
success: true,
...analysis
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
// Validate UUID format
validate(uuid) {
if (!uuid || typeof uuid !== 'string') {
return false;
}
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
return uuidRegex.test(uuid);
}
// Convert UUID to different formats
format(uuid, format) {
const parseResult = this.parse(uuid);
if (!parseResult.success) {
return parseResult;
}
const clean = uuid.replace(/-/g, '').toLowerCase();
switch (format.toLowerCase()) {
case 'standard':
case 'canonical':
return { success: true, formatted: parseResult.uuid };
case 'compact':
case 'hex':
return { success: true, formatted: clean };
case 'uppercase':
return { success: true, formatted: parseResult.uuid.toUpperCase() };
case 'lowercase':
return { success: true, formatted: parseResult.uuid.toLowerCase() };
case 'braces':
return { success: true, formatted: `{${parseResult.uuid}}` };
case 'urn':
return { success: true, formatted: `urn:uuid:${parseResult.uuid.toLowerCase()}` };
case 'base64':
const bytes = this.uuidToBytes(parseResult.uuid);
const base64 = btoa(String.fromCharCode(...bytes));
return { success: true, formatted: base64 };
default:
return {
success: false,
error: `Unknown format: ${format}`
};
}
}
// Utility functions
generateRandomBytes(length) {
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
const bytes = new Uint8Array(length);
crypto.getRandomValues(bytes);
return Array.from(bytes);
} else {
// Fallback for environments without crypto
console.warn('Using Math.random() - not cryptographically secure');
return Array.from({ length }, () => Math.floor(Math.random() * 256));
}
}
generateRandomNodeId() {
const bytes = this.generateRandomBytes(6);
bytes[0] |= 0x01; // Set multicast bit to indicate random node ID
return bytes;
}
formatUUID(components) {
return [
components[0].toString(16).padStart(8, '0'),
components[1].toString(16).padStart(4, '0'),
components[2].toString(16).padStart(4, '0'),
components[3].toString(16).padStart(2, '0') + components[4].toString(16).padStart(2, '0'),
components.slice(5).map(b => b.toString(16).padStart(2, '0')).join('')
].join('-').toUpperCase();
}
bytesToUUID(bytes) {
const hex = bytes.map(b => b.toString(16).padStart(2, '0')).join('');
return [
hex.substring(0, 8),
hex.substring(8, 12),
hex.substring(12, 16),
hex.substring(16, 20),
hex.substring(20, 32)
].join('-').toUpperCase();
}
uuidToBytes(uuid) {
const hex = uuid.replace(/-/g, '');
const bytes = [];
for (let i = 0; i < hex.length; i += 2) {
bytes.push(parseInt(hex.substr(i, 2), 16));
}
return bytes;
}
parseV1Timestamp(timeLow, timeMid, timeHigh) {
// Remove version bits
const timeHighClean = parseInt(timeHigh, 16) & 0x0fff;
// Reconstruct 60-bit timestamp
const timestamp = BigInt('0x' + timeHighClean.toString(16) + timeMid + timeLow);
// Convert to Unix timestamp (subtract UUID epoch offset)
const unixTimestamp = Number((timestamp - 0x01B21DD213814000n) / 10000n);
return {
uuid: timestamp.toString(),
unix: unixTimestamp,
date: new Date(unixTimestamp),
iso: new Date(unixTimestamp).toISOString()
};
}
checkUniqueness(uuids) {
const uniqueSet = new Set(uuids);
const duplicates = uuids.length - uniqueSet.size;
return {
total: uuids.length,
unique: uniqueSet.size,
duplicates: duplicates,
uniquenessRate: Math.round((uniqueSet.size / uuids.length) * 100),
hasDuplicates: duplicates > 0
};
}
// Compare two UUIDs
compare(uuid1, uuid2) {
try {
const clean1 = uuid1.replace(/-/g, '').toLowerCase();
const clean2 = uuid2.replace(/-/g, '').toLowerCase();
const parse1 = this.parse(uuid1);
const parse2 = this.parse(uuid2);
if (!parse1.success || !parse2.success) {
return {
success: false,
error: 'One or both UUIDs are invalid'
};
}
return {
success: true,
equal: clean1 === clean2,
uuid1: parse1,
uuid2: parse2,
sameVersion: parse1.version === parse2.version,
lexicographicalOrder: clean1.localeCompare(clean2)
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
}
// Usage examples
const uuidGen = new UUIDGenerator();
// Generate different UUID versions
console.log('Generate UUID v4 (random):');
const uuidV4 = uuidGen.generate(4);
console.log(uuidV4);
console.log('\nGenerate UUID v1 (time-based):');
const uuidV1 = uuidGen.generate(1);
console.log(uuidV1);
// Generate UUID v5 (hash-based)
console.log('\nGenerate UUID v5 (hash-based):');
uuidGen.generate(5, {
namespace: 'DNS',
name: 'example.com'
}).then(uuidV5 => {
console.log(uuidV5);
});
// Parse UUID
if (uuidV4.success) {
console.log('\nParse UUID:');
const parsed = uuidGen.parse(uuidV4.uuid);
console.log(parsed);
// Format UUID
console.log('\nFormat UUID:');
const formatted = uuidGen.format(uuidV4.uuid, 'compact');
console.log(formatted);
}
// Generate multiple UUIDs
console.log('\nGenerate Multiple UUIDs:');
const multipleUuids = uuidGen.generateMultiple(5, 4);
console.log('Uniqueness check:', multipleUuids.uniqueness);
console.log('UUID generator ready!');
UUID Standards and Compatibility
Standards Compliance:
Language Support:
UUID Best Practices
- Version Selection: Use v4 for general purposes, v1 for time-based sorting, v5 for deterministic generation
- Storage Optimization: Store as binary (16 bytes) rather than strings (36 chars) when possible
- Database Indexing: Consider using sequential UUIDs (v1, v6, v7) for better B-tree index performance
- Security Considerations: Be aware that v1 UUIDs may leak MAC addresses and timestamps
- Case Sensitivity: Standardize on lowercase representation for consistency
- Validation: Always validate UUID format and version when parsing from external sources
Common Use Cases
- Database primary keys and foreign keys
- Session identifiers and tokens
- File and document unique naming
- Distributed system coordination
- API resource identifiers
- Transaction and correlation IDs
- Message queue identifiers
- Cache keys and object identification
Advertisement
