3 poin oleh GN⁺ 2024-08-27 | 1 komentar | Bagikan ke WhatsApp
  • UUID memiliki 8 versi dari v1 hingga v8, dan angka yang lebih besar tidak berarti lebih baru atau lebih baik; tiap versi hanya mewakili metode pembuatan yang berbeda yang didefinisikan dalam RFC 9562
  • Pilihan yang umum biasanya menyempit ke v4 dan v7; v4 adalah default untuk ID acak, sedangkan v7 cocok bila perlu pengurutan berdasarkan waktu pembuatan
  • v1 dan v6 memakai bahan yang sama, tetapi v6 mengubah urutan field agar saat diurutkan hasilnya mengikuti urutan waktu pembuatan
  • v3 dan v5 membuat UUID dengan meng-hash data masukan; v3 menggunakan MD5, v5 menggunakan SHA-1, dan nilai masukan kandidatnya bisa berupa DNS dan URL
  • Jika memungkinkan, gunakan v7 alih-alih v1·v6; bila butuh UUID berbasis data masukan, pilih v5, dan bila butuh UUID yang sepenuhnya dikustomisasi, pertimbangkan v8

Cara pembuatan untuk tiap versi UUID

  • Versi UUID ada dari v1 hingga v8 dan semuanya didefinisikan dalam RFC 9562
  • UUID berbasis waktu

    • UUID Version 1 dibuat dari timestamp, penghitung monoton, dan alamat MAC
    • UUID Version 6 memakai data yang sama seperti v1, tetapi mengubah urutannya agar saat diurutkan hasilnya mengikuti waktu pembuatan
    • UUID Version 7 dibuat dari timestamp dan data acak
  • UUID acak dan kustom

    • UUID Version 4 dibuat sepenuhnya dari data acak, dan paling dekat dengan bentuk yang banyak orang bayangkan saat mendengar UUID
    • UUID Version 8 sepenuhnya bersifat kustom pengguna, kecuali field version/variant yang wajib ada di semua versi
  • UUID berbasis hash data masukan

    • UUID Version 3 dibuat dari hash MD5 atas data yang diberikan pengguna
      • Nilai masukan kandidat dalam RFC mencakup DNS dan URL
    • UUID Version 5 dibuat dari hash SHA-1 atas data yang diberikan pengguna
      • Seperti v3, DNS dan URL juga bisa menjadi kandidat masukan
  • UUID yang dicadangkan

    • UUID Version 2 dicadangkan untuk security ID dan tidak memiliki detail yang diketahui

Kriteria pemilihan nyata

  • Dalam kebanyakan kasus, pilihannya adalah v4 atau v7
  • Jika Anda hanya memerlukan ID acak, v4 adalah pilihan default yang tepat
  • Jika ID perlu bisa diurutkan, Anda bisa mempertimbangkan v7
    • Sebagai contoh, saat UUID dipakai sebagai kunci database, v7 bisa menjadi kandidat
  • v5 atau v8 lebih dekat ke penggunaan saat Anda ingin memasukkan data Anda sendiri ke dalam UUID
    • Untuk tipe seperti ini, biasanya pengguna sudah tahu kapan mereka membutuhkannya
  • Menurut RFC, v7 memperbaiki v1 dan v6, jadi jika memungkinkan sebaiknya gunakan v7 alih-alih v1·v6
    • Jika benar-benar perlu memakai v1 atau v6, Anda bisa menggunakan v6
  • v2 dicadangkan untuk penggunaan keamanan yang tidak ditentukan
  • v3 telah digantikan oleh v5 yang memakai hash lebih kuat, dan bila v3 memang dibutuhkan, kemungkinan besar penggunanya sudah mengetahui alasannya

1 komentar

 
GN⁺ 2024-08-27
Komentar Hacker News
  • Tidak adanya detail UUID v2 itu hanya berlaku jika yang dibaca cuma RFC yang memang terkenal sangat tidak jelas: https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#t...
    Memang hampir tidak pernah ditemui, tetapi ada juga UUID versi 0. Ini layak disebut karena menjadi asal bit cadangan yang memungkinkan “versi” lain kemudian didefinisikan dengan cara yang kompatibel. Riset terkait sudah saya rangkum di pustaka UUID saya: https://github.com/okeeblow/DistorteD/blob/NEW%E2%80%85SENSA...
    Karena keren, saya memutuskan untuk mendukungnya, tetapi saya masih perlu menentukan cara menangani rollover tanggal dan metode penanganan Apollo UID yang lebih lama

    • Supaya adil, RFC9562 memang mencantumkan dua dokumen spesifikasi UUID Version 2. Hanya saja RFC4122 menurut selera saya terlalu terasa seperti teks sandi
      Saya sedang mulai mengerjakan RFC informatif agar orang lebih mudah memahami tipe UUID historis yang didefinisikan di ruang Variant 0-7. Jika ingin ikut berdiskusi atau meninjau redaksinya, lihat https://github.com/yocto/draft-yocto-uuid
  • Detailnya bisa ditemukan dalam 2 menit. Klik tautan di artikelnya ke bagian definisi DCE pada RFC 9562, lalu masuk ke spesifikasinya lewat tautan pertama di paragraf itu, kemudian cari “UUID” dan buka lampiran A, semuanya ada di sana
    Namanya memang membingungkan, “Universal Unique Identifier”, tetapi semua yang diperlukan ada. Setidaknya ada baiknya penulis menekan sendiri tautan yang dia pasang di artikelnya

    • Ada dua hal yang bisa dipelajari di sini. Satu adalah membaca spesifikasi v2 UUID, dan satu lagi adalah mengetahui informasi situasional saat UUID dibuat
      Dalam konteksnya, versi-versi lain dijelaskan sebagai dihasilkan dari elemen tertentu, jadi kalimat itu jelas mengacu pada yang kedua. Kalimatnya memang agak ambigu, tetapi rasanya tidak sampai menyesatkan
    • Saya juga melakukan proses yang persis sama, lalu langsung tidak membaca artikelnya sampai habis karena terasa tidak terlalu peduli pada detail
      Meski begitu, lampirannya cukup menyenangkan dibaca seperti sebuah snapshot dari masa itu
    • Mungkin ini artikel yang ditulis language model
  • Akan bagus kalau ada standar UUID pendek seperti 73WakrfVbNJBaAmhQtEeDv atau bK7nP9xM
    Secara ketat itu memang bukan UUID karena mungkin bisa bertabrakan di suatu tempat, tetapi saya ingin kombinasi standar ID yang acak namun cukup pendek untuk diingat

    • Yang paling mendekati menurut saya adalah ULID. Panjangnya 26 karakter base32, cukup pendek, 128-bit, dan bisa diurutkan secara leksikografis
      Menurut saya alasan tidak ada standar yang lebih populer adalah karena harus ada yang dikorbankan. 128-bit punya risiko tabrakan yang rendah untuk hampir semua penggunaan, tetapi makin kecil ukurannya, makin perlu mempertimbangkan situasi spesifik dan dampak tabrakan, sehingga sulit dijadikan standar. Kalau memakai encoding lain seperti base64 atau base85 memang bisa lebih pendek, tetapi harus mengorbankan hal seperti pembedaan huruf besar-kecil dan keamanan URL: https://github.com/ulid/spec
    • Jika butuh UUID yang lebih padat, UUID yang ada bisa diubah menjadi base64 aman-URL dan dinyatakan dalam bentuk 22 karakter
      Itu hanya representasi lain dari UUID yang sama dan bisa dibalik. UUID pada akhirnya hanyalah nilai 128-bit, jadi ini bukan benar-benar transformasi, melainkan notasi alternatif
    • Bisa jadi yang dicari adalah Sqids. Ini menghasilkan ID yang jauh lebih pendek daripada UUID, tetapi tidak unik secara universal dan dibuat dari urutan bilangan bulat: https://sqids.org/
    • Biasanya orang membuat bilangan acak N-bit lalu mengenkodenya dengan base58. N bisa dipilih sesuai kebutuhan
      Keuntungan urutan monoton yang ada pada beberapa versi UUID memang hilang, tetapi base58 aman untuk URL dan tidak mengandung karakter khusus. Nilainya juga tetap bisa disimpan dalam bentuk biner. Misalnya di Postgres, Anda bisa memakai bytea alih-alih kolom teks
    • Sedang ada upaya untuk menstandarkan teknik encoding alternatif yang bisa merepresentasikan UUID 128-bit dalam bentuk teks yang lebih pendek
      Diskusinya bisa dilihat di sini: https://github.com/uuid6/new-uuid-encoding-techniques-ietf-d...
  • Timestamp pada UUID v7 membawa perubahan besar bagi Databend. Mereka memakainya untuk cepat menemukan file metadata berdasarkan timestamp di AWS S3, sehingga pekerjaan seperti vacuum menjadi jauh lebih cepat
    PR: https://github.com/datafuselabs/databend/pull/16049

    • Menarik, tetapi saya tidak langsung terpikir memakai UUID untuk pencarian berbasis waktu. Kalau saya, mungkin akan menaruh field timestamp terpisah
      Keuntungan besar UUID yang diurutkan berdasarkan waktu adalah locality yang lebih baik. Saat menambahkan entri baru ke indeks, operasinya biasanya menjadi penambahan di bagian belakang sehingga bisa lebih murah daripada penyisipan acak. Namun contention juga bisa meningkat, jadi hybrid yang menaruh sebagian bit acak di depan timestamp untuk membuat “shard” terurut juga layak dipertimbangkan. Pembacaan juga sering condong ke data terbaru, jadi berguna jika data terbaru terkumpul di satu tempat dan mudah masuk ke cache
    • Ini juga sangat bagus untuk penyimpanan key-value seperti DynamoDB. Jauh lebih rapi daripada kunci komposit dengan prefiks timestamp atau tanggal ISO, dan juga lebih baik daripada memboroskan indeks sekunder khusus timestamp
  • Sulit memahami tujuan uuid2. Saya bahkan tidak tahu ada tipe-tipe lain seperti ini, dan baru pertama kali melihat uuid2 saat meminta Xandr menghapus data pribadi saya: https://news.ycombinator.com/item?id=40913915
    Bahkan setelah membaca Wikipedia, saya tetap kurang paham mengapa setelah membuat sesuatu yang disebut “pengenal unik universal” masih ada banyak tipenya, dan mengapa beberapa di antaranya awalnya dibuat agar bisa melacak sampai ke PC asal. Saya juga penasaran apakah mencampurkan sebagian kode MAC membuat uuid2 lebih mendekati acak, atau ada alasan lain. Dari sudut pandang privasi, saya juga bertanya-tanya apakah cukup memakai pengenal panjang dengan jumlah karakter pilihan yang sangat banyak sehingga kemungkinan duplikasi praktis nol

    • Tujuan awalnya adalah mengidentifikasi pesan dalam arsitektur komputasi terdistribusi Apollo. UID dan kemudian UUID adalah cara yang dapat dibalik untuk menandai titik perpotongan dari dua dimensi
      Dua mesin mana pun dapat membuat UID/UUID yang sama untuk dua masukan yang sama, dan pihak yang menerima pesan yang teridentifikasi itu dapat mengurai pengenal tersebut kembali ke komponen asalnya. Karena dirancang sebagai label untuk pesan sementara, dua dimensinya adalah waktu dan ID perangkat keras; mula-mula nomor seri Apollo, lalu kemudian alamat perangkat keras Ethernet, dan sebagainya
      Sebagian besar kebingungan tampaknya berasal dari implementasi awal AEGIS, ketika para insinyur Apollo mulai memakai UID “canned”, yaitu UID statis dan sudah dikenal, untuk identifikasi sistem berkas. Seiring waktu, penggunaan umum UUID sepenuhnya bergeser dari pengenal sementara yang memang mengizinkan duplikasi menjadi pengenal canned yang harus menghindari duplikasi, dan dua dimensinya pun berubah menjadi acak dan acak lagi
      Sejarahnya lebih rumit. Microsoft mempekerjakan salah satu tokoh inti Apollo untuk membuat MSRPC bagi Windows NT, dan dari situlah GUID juga muncul. Tata letak field GUID berbeda dari UUID dan, tidak seperti yang dikatakan banyak sumber, itu bukan mixed-endian. Microsoft gemar memakai canned GUID bukan hanya untuk mengidentifikasi pesan RPC sementara, tetapi juga untuk hampir segala hal yang memerlukan pengenal yang sudah dikenal, seperti kelas COM, codec media, dan lain-lain. Contoh: https://gix.github.io/media-types/
      Maaf sudah menautkan repositori saya dua kali di kolom komentar yang sama, tetapi saya mulai merangkum sejarah ini di README pustaka UUID saya dan perlu melanjutkannya lagi. Apollo dimulai pada 1980, sementara draf RFC UUID Leach/Salz baru muncul pada 1998, jadi ada sangat banyak hal yang hilang dari standar modern: https://github.com/okeeblow/DistorteD/blob/NEW%E2%80%85SENSA...
  • UUID v4 pada dasarnya hanyalah pembuat byte acak dengan tanda hubung di posisi tertentu. Tidak wajib memakainya; Anda bisa langsung membuat byte acak sendiri untuk menghemat ruang
    Ini juga mengurangi hal-hal seperti tanda hubung yang tidak perlu dan informasi versi

    • UUID adalah angka 128-bit, dan representasi string dengan tanda hubung hanyalah salah satu dari beberapa cara untuk merepresentasikan angka itu
      Mirip seperti alamat IPv4 yang merupakan angka 32-bit, dan “empat kelompok yang dipisahkan titik” hanyalah salah satu representasinya. Jika Anda memandang UUID sebagai format string, berarti pemahaman paling dasarnya tentang UUID sudah keliru. Sekalipun Anda hanya menginginkan pengenal acak, menurut saya cukup keren bahwa UUID acak punya sedikit bit penanda yang mengatakan “ini memang sengaja dibuat acak”. Itu berguna ketika Anda hanya menemukan satu pengenal tanpa konteks
    • UUID v4 menetapkan 4 bit ke nilai tetap untuk menandakan bahwa itu versi 4
      Bisa diperdebatkan apakah berguna memiliki namespace berbeda di antara berbagai cara pembuatan, tetapi peluang generator bilangan acak umum menghasilkan UUIDv4 yang valid hanya 1/16. Tentu saja, jika Anda ingin membuat generator UUID sendiri, mengatur bit-bit itu dengan benar adalah hal sepele
    • Benar, tetapi bagi sebagian besar pengembang daya tariknya adalah implementasinya sederhana. Hampir semua bahasa punya pustaka UUID yang bekerja dalam satu baris
      Di Go, misalnya, cukup uuid.New().String(), tetapi jika memakai crypto/rand untuk membaca data acak lalu mengubahnya ke base64 atau hex, itu butuh lebih banyak baris dan usaha
  • Saya sarankan untuk tidak memakai versi berbasis MAC. Secara teori ini bisa mencakup semua selain v4 dan v7, tetapi v1 yang paling buruk
    v3 juga punya masalah karena MD5 sudah sangat rusak

    • MD5 “rusak” sebagai fungsi hash kriptografis. Sebagai fungsi hash non-kriptografis, itu masih sepenuhnya baik-baik saja
  • Saya tidak tahu detail selain nomor 4, tetapi hal yang benar-benar terasa absen dan berguna adalah pendekatan memakai data SHA256 dan penghitung. Bentuknya mirip PBKDF2
    Itu bisa menjadi pengenal turunan yang menjaga privasi, dan juga bisa menjadi cara longgar untuk membuktikan bahwa UUID tertentu diturunkan dari seed tertentu

    • Jika benar-benar perlu, anggap saja UUIDv4 sebagai format pengodean, lalu hasilkan keluaran 122-bit dengan algoritma kripto dan enkode sebagai UUID
      Selain itu, Anda kemungkinan akan menginginkan keluaran yang lebih panjang
    • Mirip v3, tetapi dalam bentuk yang algoritma hash-nya bisa ditentukan
  • Pakai saja v7
    Sekarang giliran para pakar keamanan untuk berkata tidak

    • Jika tanggal pembuatan bisa menjadi informasi sensitif atau UUID harus sepenuhnya tidak dapat ditebak, gunakan v4. Selain itu, gunakan v7
    • Hal yang selalu saya sayangkan dari UUID dan ULID adalah, setahu saya, tidak ada cara yang baik untuk membuatnya secara deterministik
      Dalam banyak penggunaan, akan sangat berguna bila pemrosesan ulang data tetap menghasilkan ID yang sama, tetapi saya tidak tahu cara standar untuk mencapainya
    • Saya tidak mengerti mengapa masalah terkait keamanan dianggap begitu enteng