UUID v1 Üretici

Gömülü zaman damgasıyla zaman tabanlı UUID v1 oluşturur

Biçimle

Adet:
Note:UUID v1, ana bilgisayar MAC adresini ve oluşturma zaman damgasını gömer; bu durum çoğu modern uygulama için gizlilik endişeleri doğurur. Yeni projeler için, özellikle zaman sıralı ve çözümlenebilir tanımlayıcılara ihtiyaç duymadığınız sürece UUID v4 önerilir.

UUID v1 Nedir?

UUID v1, RFC 4122'de (2005) standartlaştırılmış orijinal UUID sürümüdür. Oluşturan ana bilgisayarın MAC adresiyle yüksek hassasiyetli zaman damgasını birleştirerek benzersiz tanımlayıcılar üretir.

Zaman damgası gömülü olduğundan aynı ana bilgisayardan gelen UUID v1 değerleri zamanla monoton artar. Bu, her düğümün koordinasyon olmadan bağımsız UUID oluşturabileceği dağıtık sistemler için tasarlanmıştı.

Bugün UUID v1, büyük ölçüde UUID v7 (sıralanabilir, MAC sızıntısı yok) ve UUID v4 (tamamen rastgele, özel) tarafından yerini almıştır.

UUID v1 Anatomisi

550e8400-e29b-11d4-a716-446655440000 gibi bir UUID v1 dizesi altı farklı alan kodlar:

AlanBoyutAçıklama
time_low32 bits60 bitlik Gregoryen zaman damgasının 32 bitlik düşük alanı (15 Ekim 1582'den itibaren 100 nanosaniyelik aralıklar)
time_mid16 bits60 bitlik zaman damgasının orta 16 bitlik alanı
time_hi_and_version16 bits60 bitlik zaman damgasının üst 12 biti artı 4 bitlik sürüm numarası (her zaman <code>1</code>)
clock_seq_hi_res8 bits2 bitlik RFC 4122 varyant işaretçisiyle birleştirilen 6 bitlik saat dizisi yüksek alanı
clock_seq_low8 bitsSaat dizisinin alt 8 biti
node48 bits48 bitlik düğüm tanımlayıcısı — genellikle oluşturan ağ arayüzünün MAC adresi

Saat dizisi alanı 14 bitlik bir sayaçtır. Sistem saati geriye gittiğinde veya sistem yeniden başlatıldığında artırılır.

UUID v1 Zaman Damgasını Çözme

60 bitlik zaman damgası UUID'de üç alana dağıtılmıştır. Oluşturma zamanını yeniden oluşturmak için:

  1. time_low (bayt 0–3), time_mid (bayt 4–5) ve time_hi'yı (bayt 6–7, sürüm nibble'ı çıkarılmış) çıkarın
  2. Yeniden birleştirin: (time_hi &lt;&lt; 48) | (time_mid &lt;&lt; 32) | time_low
  3. Sonuç, 15 Ekim 1582'den (Gregoryen takvim dönemi) itibaren 100 nanosaniyelik aralıkların 60 bitlik sayısıdır
  4. Gregoryen-Unix farkını çıkarın: 122.192.928.000.000.000
  5. 100 nanosaniyelik aralıkları milisaniyeye dönüştürmek için 10.000'e bölün
  6. Date nesnesi oluşturmak için Unix milisaniye zaman damgası olarak kullanın
  7. İnsan tarafından okunabilir çıktı için ISO 8601 biçiminde biçimlendirin

Zaman damgası hassasiyeti 100 nanosaniyedir — UUID v7'nin milisaniye hassasiyetinden çok daha ince.

Gizlilik Endişeleri

UUID v1'in en önemli dezavantajı, düğüm alanında oluşturan ana bilgisayarın MAC adresini gömmesidir.

UUID v1 elde eden bir saldırgan şunları belirleyebilir: (1) ID'nin yaklaşık oluşturma zamanı, (2) oluşturan ana bilgisayarın MAC adresi ve (3) ID oluşturma hızı.

Bu nedenle UUID v1, bu bilgiyi açıklamaktan çekinmiyorsanız kamuya yönelik tanımlayıcı olarak kullanılmamalıdır.

UUID v1'in Hâlâ Uygun Olduğu Durumlar

Apache Cassandra birincil anahtarları
Cassandra, UUID v1'i (TimeUUID türü aracılığıyla) temel tasarım kalıbı olarak kullanır.
Eski dağıtık sistemler
UUID v7'den önce (2024 öncesi) oluşturulmuş ve zaman sıralı UUID'lere dayanan sistemler.
Denetim ve olay günlükleri
Oluşturan ana bilgisayar kimliğinin bilindiği ve güvenildiği durumlarda MAC adresini gömmek ek izlenebilirlik sağlayabilir.
Dahili tanımlayıcılar
MAC adresi açıklamasının endişe verici olmadığı kontrollü dahili sistemlerin dışına hiçbir zaman çıkmayan ID'ler.
Ayrı zaman damgası sütunu olmadan zaman aralığı sorguları
Gömülü zaman damgası, satırları oluşturma zamanına göre filtrelemek için çözülebilir.
Eski UUID v1 oluşturucularıyla birlikte çalışabilirlik
Bunları üreten harici sistemlerden UUID v1 değerleri alırken veya işlerken.

UUID v1 ile UUID v7 Karşılaştırması

UUID v7, zaman sıralı tanımlayıcılar için UUID v1'in modern halefidir:

KonuUUID v1UUID v7
Dönem / Zaman TabanıGregoryen dönemi (15 Ekim 1582)Unix dönemi (1 Ocak 1970)
Hassasiyet100 nanosaniye1 milisaniye
Düğüm TanımlayıcısıMAC adresi (ana bilgisayar kimliğini sızdırır)Rastgele (özel)
GizlilikMAC adresini ve oluşturma zaman damgasını sızdırırGömülü ana bilgisayar bilgisi yok
Veritabanı dizin performansıİyi — ana bilgisayar başına sıralıMükemmel — tüm oluşturucularda k-sıralanabilir
StandartRFC 4122 (2005)RFC 9562 (2024)

Yeni projeler için UUID v7, UUID v1'in önerilen halefidir.

Kod Örnekleri

UUID v1 üretimi tarayıcılarda veya Node.js'de yerel olarak mevcut değildir. uuid npm paketini kullanın:

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))
}

Sıkça Sorulan Sorular

UUID v1'den zaman damgasını çözebilir miyim?
Evet. Oluşturma zaman damgası bir UUID v1 dizesinden tamamen kurtarılabilir.
MAC adresi UUID v1'de her zaman mevcut mu?
Zorunlu değil. RFC 4122, uygulamaların MAC adresi için rastgele oluşturulmuş 48 bitlik bir değeri ikame etmesine izin verir.
UUID v1 zaman damgası neden 1582'yi dönem olarak kullanıyor?
Gregoryen takvim reformu 15 Ekim 1582'de yürürlüğe girdi. 60 bitlik zaman damgası alanı yaklaşık 3400 MS'ye kadar benzersizliği koruyacak yeterliliktedir.
UUID v1 ile UUID v7 karşılaştırması — v1'i ne zaman kullanmalıyım?
UUID v1 kullanmanın temel nedeni mevcut sistemlerle uyumluluktur — özellikle TimeUUID türü olarak v1 kullanan Apache Cassandra. Tüm yeni sistemler için UUID v7 kesinlikle daha iyidir.
UUID v1 değerleri çakışabilir mi?
Teoride, aynı MAC adresi aynı 100 nanosaniyelik aralıkta iki UUID üretirse ve saat dizisi aynıysa. Doğru uygulanan sistemlerde çakışmalar son derece nadirdir.