Nama dan namespace dapat digunakan untuk membuat hierarki (sangat mungkin) UUID unik.
Secara kasar, UUID tipe 3 atau tipe 5 dihasilkan dengan melakukan hashing bersama pengenal namespace dengan sebuah nama. UUID tipe 3 menggunakan MD5 dan UUID tipe 5 menggunakan SHA1. Hanya 128-bit yang tersedia dan 5 bit digunakan untuk menentukan jenisnya, jadi semua bit hash tidak membuatnya menjadi UUID. (Juga MD5 dianggap rusak secara kriptografis, dan SHA1 berada pada tahap terakhirnya, jadi jangan gunakan ini untuk memverifikasi data yang harus "sangat aman"). Yang mengatakan, ini memberi Anda cara untuk membuat fungsi "hash" yang dapat diulang / diverifikasi yang memetakan nama yang mungkin hierarkis ke nilai 128-bit yang mungkin unik, berpotensi bertindak seperti hash hierarkis atau MAC.
Misalkan Anda memiliki penyimpanan (key, value), tetapi hanya mendukung satu namespace. Anda dapat membuat banyak ruang nama logis berbeda menggunakan tipe 3 atau tipe 5 UUID. Pertama, buat UUID root untuk setiap namespace. Ini bisa berupa UUID tipe 1 (host + timestamp) atau tipe 4 (acak) selama Anda menyimpannya di suatu tempat. Cara lainnya, Anda dapat membuat satu UUID acak untuk root Anda (atau menggunakan null
UUID: 00000000-0000-0000-0000-000000000000
sebagai root) dan kemudian membuat UUID yang dapat direproduksi untuk setiap namespace menggunakan " uuid -v5 $ROOTUUID $NAMESPACENAME
". Sekarang Anda dapat membuat UUID unik untuk kunci dalam namespace menggunakan "uuid -v5 $NAMESPACEUUID $KEY
". UUID ini dapat dilemparkan ke penyimpanan nilai kunci tunggal dengan probabilitas tinggi untuk menghindari tabrakan. Proses ini dapat diulangi secara rekursif sehingga jika misalnya," nilai "yang terkait dengan kunci UUID pada gilirannya mewakili semacam ruang nama logis" "seperti bucket, container, atau direktori, UUID-nya dapat digunakan secara bergantian untuk menghasilkan UUID yang lebih hierarkis.
UUID tipe 3 atau tipe 5 yang dihasilkan menyimpan hash (sebagian) dari id namespace dan nama-dalam-namespace (kunci). Itu tidak lebih memegang UUID namespace daripada pesan MAC menyimpan konten pesan yang dikodekannya. Namanya adalah string "arbitrary" (oktet) dari perspektif algoritme uuid. Namun artinya tergantung pada aplikasi Anda. Ini bisa berupa nama file dalam direktori logis, id objek dalam penyimpanan objek, dan sebagainya.
Meskipun ini bekerja dengan baik untuk sejumlah besar ruang nama dan kunci, pada akhirnya akan kehabisan tenaga jika Anda membidik sejumlah besar kunci yang unik dengan probabilitas sangat tinggi. Entri Wikipedia untuk Masalah Ulang Tahun (alias Paradoks Ulang Tahun) menyertakan tabel yang memberikan kemungkinan setidaknya satu tabrakan untuk berbagai nomor kunci dan ukuran tabel. Untuk 128-bit, hashing 26 miliar kunci dengan cara ini memiliki kemungkinan tabrakan p=10^-18
(dapat diabaikan), tetapi 26 triliun kunci, meningkatkan kemungkinan setidaknya satu tabrakan menjadi p=10^-12
(satu dalam satu triliun), dan hashing 26*10^15
kunci, meningkatkan kemungkinan setidaknya satu tabrakan kep=10^-6
(satu dari sejuta). Menyesuaikan 5 bit yang menyandikan jenis UUID, itu akan habis lebih cepat, sehingga satu triliun kunci memiliki kira-kira peluang 1 dalam satu triliun untuk mengalami satu tabrakan.
Lihat http://en.wikipedia.org/wiki/Birthday_problem#Probability_table untuk tabel probabilitas.
Lihat http://www.ietf.org/rfc/rfc4122.txt untuk detail lebih lanjut tentang pengkodean UUID.
UUID Tipe 3 dan Tipe 5 hanyalah teknik memasukkan hash ke dalam UUID.
Sebuah hash SHA1 menghasilkan 160 bit (20 byte); hasil hash diubah menjadi UUID.
Dengan hash 20-byte dari SHA1:
(Perhatikan bahwa dua bit pertama dari '9' masing-masing sudah menjadi 1 dan 0, jadi ini tidak berpengaruh).
Apa yang saya hash?
Anda mungkin bertanya-tanya apa yang harus saya hash. Pada dasarnya, Anda mencirikan rangkaian:
Anda memberi awalan string Anda dengan apa yang disebut namespace untuk mencegah konflik nama.
The UUID RFC pra-mendefinisikan empat ruang nama untuk Anda:
NameSpace_DNS
: {6ba7b810-9dad-11d1-80b4-00c04fd430c8}NameSpace_URL
: {6ba7b811-9dad-11d1-80b4-00c04fd430c8}NameSpace_OID
: {6ba7b812-9dad-11d1-80b4-00c04fd430c8}NameSpace_X500
: {6ba7b814-9dad-11d1-80b4-00c04fd430c8}Jadi, Anda bisa melakukan hash bersama:
RFC kemudian menjelaskan cara:
Inti dasarnya adalah hanya mengambil 128 bit pertama, memasukkan a ke
5
dalam tipe record, dan kemudian menetapkan dua bit pertama dariclock_seq_hi_and_reserved
bagian tersebut masing-masing ke 1 dan 0.Lebih banyak contoh
Sekarang Anda memiliki fungsi yang menghasilkan apa yang disebut Nama , Anda dapat memiliki fungsi tersebut (dalam pseudo-code):
(Perhatikan bahwa endian-ness sistem Anda dapat memengaruhi indeks dari byte di atas)
Anda dapat melakukan panggilan:
Sekarang kembali ke pertanyaan Anda
The namespace adalah apa pun UUID Anda seperti. Ini bisa menjadi salah satu yang ditentukan sebelumnya, atau Anda bisa membuatnya sendiri, misalnya:
Namanya hanyalah teks yang ingin Anda tambahkan ke namespace, lalu di-hash, dan dimasukkan ke dalam UUID:
sumber
Namespace_RectalForeignExtractedObject
saya akan melakukannya.Nama tidak lebih dari pengenal yang unik dalam beberapa namespace. Masalahnya adalah bahwa namespace seringkali cukup kecil dan nama-nama di satu sering bertabrakan dengan nama di tempat lain. Misalnya, nomor pelat (nama) mobil saya unik di dalam ruang nama DMV negara bagian saya, tetapi mungkin tidak unik di dunia; DMV negara bagian lain mungkin telah menggunakan nama yang sama di namespace mereka sendiri. Heck, orang lain mungkin memiliki nomor telepon (nama) yang juga cocok karena itu adalah namespace lain, dll.
UUID dapat dilihat sebagai menempati satu namespace yang sangat luas sehingga dapat memberikan nama yang unik untuk semuanya ; itulah yang dimaksud dengan "universal". Tapi bagaimana Anda memetakan nama yang ada di namespace lain ke UUID?
Salah satu solusi yang jelas adalah membuat UUID (V1 atau V4) untuk setiap item untuk menggantikan nama lama di ruang nama yang saling terpisah. Kelemahannya adalah mereka jauh lebih besar, Anda harus mengkomunikasikan semua nama baru kepada semua orang yang memiliki salinan dataset Anda, memperbarui semua API Anda, dll. Kemungkinannya Anda tidak bisa benar-benar menyingkirkan nama lama seluruhnya Lagi pula, yang berarti sekarang setiap item memiliki dua nama, jadi apakah Anda membuat semuanya lebih baik atau lebih buruk?
Di sinilah peran V3 / V5. UUID terlihat sama acaknya dengan V4 tetapi sebenarnya deterministik; siapa pun yang memiliki UUID yang tepat untuk namespace kemudian dapat secara mandiri menghasilkan UUID yang sama untuk nama tertentu dalam namespace tersebut. Anda tidak perlu mempublikasikannya sama sekali atau bahkan membuatnya terlebih dahulu karena siapa pun dapat membuatnya dengan cepat sesuai kebutuhan!
Nama DNS dan URL adalah ruang nama yang sangat umum digunakan, jadi UUID standar diterbitkan untuk itu; ASN.1 OID dan nama X.500 tidak umum, tetapi badan standar menyukainya, jadi mereka menerbitkan UUID namespace standar untuk mereka juga.
Untuk semua namespace lainnya, Anda harus membuat UUID namespace Anda sendiri (V1 atau V4) dan mengomunikasikannya kepada siapa pun yang membutuhkannya. Jika Anda memiliki beberapa ruang nama, harus menerbitkan UUID untuk masing-masing ruang nama jelas tidak ideal.
Di sinilah hierarki berperan: Anda membuat satu UUID "dasar" (jenis apa pun), lalu menggunakannya sebagai namespace untuk menamai namespace Anda yang lain! Dengan begitu, Anda hanya perlu mempublikasikan UUID dasar (atau menggunakan yang sudah jelas), dan semua orang dapat menghitung sisanya.
Sebagai contoh, mari tetap kita ingin membuat beberapa UUID untuk StackOverflow; yang memiliki nama yang jelas dalam namespace DNS, jadi dasarnya jelas:
StackOverflow sendiri memiliki ruang nama terpisah untuk pengguna, pertanyaan, jawaban, komentar, dll., Tetapi itu juga cukup jelas:
Pertanyaan khusus ini adalah # 10867405, jadi UUID-nya adalah:
Perhatikan bahwa tidak ada yang acak dalam proses ini, jadi siapa pun yang mengikuti logika yang sama akan mendapatkan jawaban yang sama, namun namespace UUID sangat luas sehingga (secara efektif, mengingat keamanan hash kriptografi 122-bit) tidak pernah bertabrakan dengan sebuah UUID dihasilkan dari namespace / pasangan nama lainnya.
sumber