UUID v1 জেনারেটর
এমবেডেড টাইমস্ট্যাম্প সহ টাইম-ভিত্তিক UUID v1 তৈরি করুন
…
ফরম্যাট
What is UUID v1?
UUID v1 is the original UUID version, standardised in RFC 4122 (2005). It generates unique identifiers by combining a high-precision timestamp with the MAC address of the generating host, plus a short clock sequence to handle sub-timestamp resolution.
Because the timestamp is embedded, UUID v1 values from the same host are monotonically increasing over time — making them naturally ordered. This was designed for distributed systems where each node could generate UUIDs independently without coordination.
Today UUID v1 is largely superseded by UUID v7 (sortable, no MAC leakage) and UUID v4 (fully random, private). It remains in use in systems like Apache Cassandra and legacy distributed databases.
Anatomy of a UUID v1
A UUID v1 string like 550e8400-e29b-11d4-a716-446655440000 encodes six distinct fields:
| Field | Size | Description |
|---|---|---|
| time_low | 32 bits | 32-bit low field of the 60-bit Gregorian timestamp (100-nanosecond intervals since Oct 15, 1582) |
| time_mid | 16 bits | Middle 16-bit field of the 60-bit timestamp |
| time_hi_and_version | 16 bits | Top 12 bits of the 60-bit timestamp plus the 4-bit version number (always <code>1</code>) |
| clock_seq_hi_res | 8 bits | 6-bit clock sequence high field combined with the 2-bit RFC 4122 variant marker |
| clock_seq_low | 8 bits | Lower 8 bits of the clock sequence |
| node | 48 bits | 48-bit node identifier — typically the MAC address of the generating network interface, or a random 48-bit value if no MAC is available |
The clock sequence field (clock_seq_hi_res + clock_seq_low) is a 14-bit counter. It is incremented whenever the system clock moves backward (e.g. NTP adjustment) or when the system restarts without persisting the last known timestamp. This prevents duplicate UUIDs from being generated if the clock is not monotonically advancing.
Decoding the UUID v1 Timestamp
The 60-bit timestamp is scattered across three fields in the UUID. To reconstruct the generation time:
- Extract
time_low(bytes 0–3),time_mid(bytes 4–5), andtime_hi(bytes 6–7, minus the version nibble) - Reassemble:
(time_hi << 48) | (time_mid << 32) | time_low - The result is a 60-bit count of
100-nanosecond intervalssince October 15, 1582 (the Gregorian calendar epoch) - Subtract the Gregorian-to-Unix offset: 122,192,928,000,000,000 (100-ns intervals between Oct 15 1582 and Jan 1 1970)
- Divide by
10,000to convert 100-nanosecond intervals to milliseconds - Use the result as a
Unix millisecond timestampto construct a Date object - Format as
ISO 8601for human-readable output
The timestamp precision is 100 nanoseconds — far finer than UUID v7's millisecond precision. However, in practice most operating systems do not expose sub-millisecond clock resolution, so the lower bits are often zero or synthesised.
Privacy Concerns
The most significant drawback of UUID v1 is that it embeds the MAC address of the generating host in the node field. This means every UUID v1 carries a permanent, globally unique fingerprint of the machine that generated it.
An adversary who obtains a UUID v1 can determine: (1) the approximate time the ID was generated, (2) the MAC address of the generating host, and (3) by analysing multiple UUIDs, the rate at which IDs are being generated.
For this reason, UUID v1 should never be used as a public-facing identifier (e.g. in URLs or API responses) unless you are comfortable disclosing this information. RFC 4122 itself notes that a system may use a random 48-bit value instead of the MAC address, but many implementations do not.
When UUID v1 Is Still Appropriate
UUID v1 vs UUID v7
UUID v7 is the modern successor to UUID v1 for time-ordered identifiers. Here is a direct comparison:
| Aspect | UUID v1 | UUID v7 |
|---|---|---|
| Epoch / Time Base | Gregorian epoch (Oct 15, 1582) | Unix epoch (Jan 1, 1970) |
| Precision | 100 nanoseconds | 1 millisecond |
| Node Identifier | MAC address (leaks host identity) | Random (private) |
| Privacy | Leaks MAC address and generation timestamp | No host information embedded |
| DB index performance | Good — sequential per host | Excellent — k-sortable across all generators |
| Standard | RFC 4122 (2005) | RFC 9562 (2024) |
For new projects, UUID v7 is the recommended replacement for UUID v1. It provides similar time-ordering guarantees without the privacy implications of embedding the host MAC address.
Code Examples
UUID v1 generation is not available natively in browsers or Node.js. Use the uuid npm package:
// Generate a UUID v1 using the Web Crypto API
function generateUuidV1() {
const buf = new Uint8Array(16)
crypto.getRandomValues(buf)
const ms = BigInt(Date.now())
const gregorianOffset = 122192928000000000n
const t = ms * 10000n + gregorianOffset
const tLow = Number(t & 0xFFFFFFFFn)
const tMid = Number((t >> 32n) & 0xFFFFn)
const tHiVer = Number((t >> 48n) & 0x0FFFn) | 0x1000 // version 1
const clockSeq = (buf[8] & 0x3F) | 0x80 // variant 10xxxxxx
const clockSeqLow = buf[9]
const hex = (n, pad) => n.toString(16).padStart(pad, '0')
const node = [...buf.slice(10)].map(b => b.toString(16).padStart(2, '0')).join('')
return `${hex(tLow,8)}-${hex(tMid,4)}-${hex(tHiVer,4)}-${hex(clockSeq,2)}${hex(clockSeqLow,2)}-${node}`
}
// Extract the embedded timestamp from a UUID v1
function extractTimestamp(uuid) {
const parts = uuid.split('-')
const tHex = parts[2].slice(1) + parts[1] + parts[0]
const t = BigInt('0x' + tHex)
const ms = (t - 122192928000000000n) / 10000n
return new Date(Number(ms))
}
const id = generateUuidV1()
console.log(id) // e.g. "1eb5e8b0-6b4d-11ee-9c45-a1f2b3c4d5e6"
console.log(extractTimestamp(id)) // e.g. 2023-10-15T12:34:56.789Zimport uuid from datetime import datetime, timezone # Generate UUID v1 (uses MAC address by default) uid = uuid.uuid1() print(uid) # Extract embedded timestamp # uuid.time is 100-ns intervals since Oct 15, 1582 GREGORIAN_OFFSET = 122192928000000000 # 100-ns intervals ts_100ns = uid.time ts_ms = (ts_100ns - GREGORIAN_OFFSET) // 10000 dt = datetime.fromtimestamp(ts_ms / 1000, tz=timezone.utc) print(dt.isoformat()) # e.g. "2023-10-15T12:34:56.789000+00:00"
package main
import (
"fmt"
"time"
"github.com/google/uuid" // go get github.com/google/uuid
)
func main() {
id, _ := uuid.NewUUID() // UUID v1
fmt.Println(id)
// Extract timestamp from UUID v1
// uuid.Time is 100-ns ticks since Oct 15, 1582
t := id.Time()
sec := int64(t)/1e7 - 12219292800 // convert to Unix seconds
nsec := (int64(t) % 1e7) * 100
ts := time.Unix(sec, nsec).UTC()
fmt.Println(ts.Format(time.RFC3339Nano))
}