UUID v1 Generator

Menghasilkan UUID v1 berbasis waktu dengan cap waktu yang tertanam

Format

Jumlah:
Note:UUID v1 menyematkan alamat MAC host dan timestamp pembuatan, yang menimbulkan masalah privasi untuk sebagian besar aplikasi modern. Untuk proyek baru, UUID v4 direkomendasikan.

Apa itu UUID v1?

UUID v1 adalah versi UUID asli, distandarisasi dalam RFC 4122 (2005). UUID v1 menghasilkan identifier unik dengan menggabungkan timestamp presisi tinggi dengan alamat MAC host yang menghasilkan.

Karena timestamp tertanam, nilai UUID v1 dari host yang sama meningkat secara monoton dari waktu ke waktu — membuatnya secara alami terurut.

Saat ini UUID v1 sebagian besar telah digantikan oleh UUID v7 (dapat diurutkan, tanpa kebocoran MAC) dan UUID v4 (sepenuhnya acak, privat). UUID v1 masih digunakan dalam sistem seperti Apache Cassandra.

Anatomi UUID v1

String UUID v1 seperti 550e8400-e29b-11d4-a716-446655440000 mengkodekan enam field berbeda:

FieldUkuranDeskripsi
time_low32 bitsField rendah 32-bit dari timestamp Gregorian 60-bit (interval 100 nanodetik sejak 15 Okt 1582)
time_mid16 bitsField tengah 16-bit dari timestamp 60-bit
time_hi_and_version16 bits12 bit atas dari timestamp 60-bit plus nomor versi 4-bit (selalu <code>1</code>)
clock_seq_hi_res8 bitsField tinggi urutan jam 6-bit dikombinasikan dengan penanda varian RFC 4122 2-bit
clock_seq_low8 bits8 bit bawah dari urutan jam
node48 bitsIdentifier node 48-bit — biasanya alamat MAC dari antarmuka jaringan yang menghasilkan

Field urutan jam adalah penghitung 14-bit. Ini diinkrementasi setiap kali jam sistem mundur.

Mendekode Timestamp UUID v1

Timestamp 60-bit tersebar di tiga field dalam UUID. Untuk merekonstruksi waktu pembuatan:

  1. Ekstrak time_low (byte 0–3), time_mid (byte 4–5), dan time_hi (byte 6–7, minus nibble versi)
  2. Susun ulang: (time_hi &lt;&lt; 48) | (time_mid &lt;&lt; 32) | time_low
  3. Hasilnya adalah hitungan 60-bit dari interval 100 nanodetik sejak 15 Oktober 1582 (epoch kalender Gregorian)
  4. Kurangi offset Gregorian-ke-Unix: 122.192.928.000.000.000
  5. Bagi dengan 10.000 untuk mengkonversi interval 100 nanodetik ke milidetik
  6. Gunakan hasilnya sebagai timestamp milidetik Unix untuk membangun objek Date
  7. Format sebagai ISO 8601 untuk output yang dapat dibaca manusia

Presisi timestamp adalah 100 nanodetik — jauh lebih halus dari presisi milidetik UUID v7.

Masalah Privasi

Kelemahan paling signifikan dari UUID v1 adalah bahwa UUID v1 menyematkan alamat MAC host yang menghasilkan di field node.

Penyerang yang mendapatkan UUID v1 dapat menentukan: (1) perkiraan waktu ID dibuat, (2) alamat MAC host yang menghasilkan, dan (3) dengan menganalisis beberapa UUID, laju pembuatan ID.

Oleh karena itu, UUID v1 tidak boleh pernah digunakan sebagai identifier yang menghadap publik kecuali Anda nyaman mengungkapkan informasi ini.

Kapan UUID v1 Masih Tepat

Kunci primer Apache Cassandra
Cassandra menggunakan UUID v1 (melalui tipe TimeUUID) sebagai pola desain inti.
Sistem terdistribusi warisan
Sistem yang dibangun sebelum UUID v7 ada (sebelum 2024) yang bergantung pada UUID berurutan timestamp.
Log audit dan acara
Ketika identitas host penghasil diketahui dan dipercaya, menyematkan alamat MAC dapat memberikan keterlacakan tambahan.
Identifier internal
ID yang tidak pernah diekspos di luar sistem internal yang terkontrol.
Kueri rentang waktu tanpa kolom timestamp terpisah
Timestamp yang tertanam dapat didekode untuk memfilter baris berdasarkan waktu pembuatan.
Interoperabilitas dengan generator UUID v1 lama
Saat menerima atau memproses nilai UUID v1 dari sistem eksternal.

UUID v1 vs UUID v7

UUID v7 adalah penerus modern UUID v1 untuk identifier berurutan waktu:

AspekUUID v1UUID v7
Epoch / Basis WaktuEpoch Gregorian (15 Okt 1582)Epoch Unix (1 Jan 1970)
Presisi100 nanodetik1 milidetik
Identifier NodeAlamat MAC (membocorkan identitas host)Acak (privat)
PrivasiMembocorkan alamat MAC dan timestamp pembuatanTidak ada informasi host yang tertanam
Performa indeks DBBaik — berurutan per hostSangat baik — k-sortable di semua generator
StandarRFC 4122 (2005)RFC 9562 (2024)

Untuk proyek baru, UUID v7 adalah pengganti yang direkomendasikan untuk UUID v1.

Contoh Kode

Pembuatan UUID v1 tidak tersedia secara native di browser atau Node.js. Gunakan paket npm uuid:

JavaScript (browser)
// 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.789Z
Python
import 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"
Go
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))
}

Pertanyaan yang Sering Diajukan

Bisakah saya mendekode timestamp dari UUID v1?
Ya. Timestamp pembuatan dapat sepenuhnya dipulihkan dari string UUID v1.
Apakah alamat MAC selalu ada di UUID v1?
Tidak selalu. RFC 4122 mengizinkan implementasi untuk mengganti nilai 48-bit yang dihasilkan secara acak untuk alamat MAC.
Mengapa timestamp UUID v1 menggunakan 1582 sebagai epoch?
Reformasi kalender Gregorian berlaku pada 15 Oktober 1582. Timestamp UUID v1 didefinisikan relatif terhadap tanggal ini.
UUID v1 vs UUID v7 — kapan saya masih menggunakan v1?
Alasan utama menggunakan UUID v1 hari ini adalah kompatibilitas dengan sistem yang ada — khususnya Apache Cassandra.
Bisakah nilai UUID v1 bertabrakan?
Secara teori, dua nilai UUID v1 dapat bertabrakan jika alamat MAC yang sama menghasilkan dua UUID dalam interval 100 nanodetik yang sama.