UUID sürümleri ve ne zaman kullanılmaları gerektiği
(ntietz.com)- UUID'nin v1'den v8'e kadar 8 sürümü vardır; daha yüksek sayı daha yeni ya da daha iyi olduğu anlamına gelmez, yalnızca farklı üretim yöntemlerinin RFC 9562'de tanımlandığını gösterir
- Yaygın seçenekler genellikle v4 ve v7'ye indirgenir; v4 rastgele ID'ler için varsayılan seçimdir, v7 ise oluşturulma zamanına göre sıralama gerektiğinde uygundur
- v1 ve v6 aynı bileşenleri kullanır, ancak v6 alan sırasını değiştirerek sıralandığında oluşturulma zamanına göre dizilmesini sağlar
- v3 ve v5, girdi verisini hash'leyerek UUID üretir; v3 MD5, v5 ise SHA-1 kullanır ve olası girdi değerleri arasında DNS ile URL bulunabilir
- Mümkünse v1·v6 yerine v7 kullanmak, girdi verisine dayalı UUID gerekiyorsa v5'i, tamamen kullanıcı tanımlı UUID gerekiyorsa v8'i değerlendirmek pratik bir yaklaşımdır
UUID sürümlerine göre üretim yöntemleri
- UUID sürümleri v1'den v8'e kadar uzanır ve hepsi RFC 9562'de tanımlanmıştır
-
Zaman tabanlı UUID'ler
- UUID Version 1, timestamp, monoton sayaç ve MAC adresi kullanılarak üretilir
- UUID Version 6, v1 ile aynı verileri kullanır ancak sıralandığında oluşturulma zamanına göre dizilmesi için düzeni değiştirir
- UUID Version 7, timestamp ve rastgele verilerle üretilir
-
Rastgele·kullanıcı tanımlı UUID'ler
- UUID Version 4, tamamen rastgele veriyle üretilir ve birçok kişinin UUID denince aklına gelen biçime en yakın sürümdür
- UUID Version 8, tüm sürümlerde zorunlu olan version/variant alanları dışında tamamen kullanıcı tanımlıdır
-
Girdi verisinin hash'ine dayalı UUID'ler
- UUID Version 3, kullanıcının sağladığı verinin MD5 hash'i ile üretilir
- RFC'deki olası girdi değerleri arasında DNS ve URL vardır
- UUID Version 5, kullanıcının sağladığı verinin SHA-1 hash'i ile üretilir
- v3'te olduğu gibi DNS ve URL girdi adayı olabilir
- UUID Version 3, kullanıcının sağladığı verinin MD5 hash'i ile üretilir
-
Ayrılmış UUID'ler
- UUID Version 2, güvenlik kimlikleri için ayrılmıştır ve bilinen bir ayrıntısı yoktur
Gerçek seçim ölçütleri
- Çoğu durumda seçenek v4 veya v7'dir
- Yalnızca rastgele bir ID gerekiyorsa v4 uygun varsayılan seçimdir
- ID'nin sıralanabilir olması gerekiyorsa v7 düşünülebilir
- Örneğin UUID bir veritabanı anahtarı olarak kullanılacaksa v7 aday olabilir
- v5 veya v8, UUID içine kendi verinizi yerleştirmek istediğiniz durumlara daha yakındır
- Bu tür durumlarda kullanıcı çoğunlukla buna ihtiyaç duyduğunu zaten bilir
- RFC'ye göre v7, v1 ve v6'yı iyileştirir; bu yüzden mümkünse v1·v6 yerine v7 kullanılmalıdır
- v1 veya v6 gerçekten gerekiyorsa v6 kullanılabilir
- v2, belirtilmemiş güvenlik amaçları için ayrılmıştır
- v3, daha güçlü hash kullanan v5 ile yer değiştirmiştir; v3'ün gerekli olduğu durumlarda da kullanıcı büyük olasılıkla bunun farkındadır
1 yorum
Hacker News yorumları
UUID v2 ayrıntılarının olmadığı söylenen durum, sadece kötü şöhretli derecede belirsiz RFC okunduğunda geçerli: https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#t...
Neredeyse hiç karşılaşılmasa da version 0 UUID diye bir şey de var. Sonradan başka “sürümler”in uyumlu şekilde tanımlanabilmesini sağlayan ayrılmış bitlerin kaynağı olduğu için anılmayı hak ediyor. Bununla ilgili araştırmayı UUID kütüphanemde derledim: https://github.com/okeeblow/DistorteD/blob/NEW%E2%80%85SENSA...
Havalı olduğu için desteklemeye karar verdim ama tarih rollover’ı ve daha eski Apollo UID işleme biçimini hâlâ belirlemem gerekiyor
0-7 Variant alanında tanımlanmış tarihsel UUID türlerini insanların anlamasına yardımcı olacak bilgilendirici bir RFC taslağı üzerinde çalışmaya başlıyorum. Tartışmaya katılmak veya metni gözden geçirmek isterseniz https://github.com/yocto/draft-yocto-uuid adresine bakabilirsiniz
Ayrıntıları 2 dakikada bulabildim. Yazıdaki bağlantıya tıklayıp RFC 9562’nin DCE tanımı bölümüne gidiyorsunuz, oradaki ilk bağlantıdan spesifikasyona giriyorsunuz, sonra “UUID” diye aratıp Ek A’ya geçiyorsunuz; hepsi orada
Adı kafa karıştırıcı biçimde “Universal Unique Identifier” ama gereken her şey var. En azından kendi yazısına koyduğu bağlantılara tıklayabilirdi
Bağlam gereği diğer sürümlerin belli bileşenlerden üretildiği anlatılıyor; bu yüzden ilgili cümle açıkça ikincisinden söz ediyor. Biraz muğlak olsa da yanıltıcı denecek kadar değil
Yine de ek kısmı, dönemin bir anlık görüntüsü gibi okunması bakımından eğlenceliydi
73WakrfVbNJBaAmhQtEeDvya dabK7nP9xMgibi kısa UUID standardı olsa güzel olurduTeknik olarak bir yerde çakışma ihtimali olacağı için UUID sayılmaz ama rastgele olup aynı zamanda ezberlenebilecek kadar kısa bir ID standardı kombinasyonu istiyorum
Daha popüler bir standardın olmama nedeni, bir şeylerden vazgeçmek zorunda olmanız diye düşünüyorum. 128 bit, neredeyse tüm kullanım alanlarında düşük çakışma riski sunuyor; ama daha küçüldükçe somut senaryo ile çakışmanın etkisini değerlendirmek gerekiyor, bu da standartlaştırmayı zorlaştırıyor. base64 ya da base85 gibi başka kodlamalar daha kısa olabilir ama büyük/küçük harf duyarlılığı veya URL güvenliği gibi şeylerden ödün verirsiniz: https://github.com/ulid/spec
Bu sadece aynı UUID’nin farklı bir gösterimi, ayrıca tersine çevrilebilir. UUID sonuçta 128 bitlik bir değer; gerçek bir dönüşümden çok alternatif bir yazımdır
Böylece bazı UUID sürümlerinin sunduğu monoton sıralama avantajını kaybedersiniz ama base58 URL için güvenlidir ve özel karakter içermez. Değerleri yine ikili olarak saklayabilirsiniz. Örneğin Postgres’te metin sütunu yerine
byteakullanabilirsinizTartışmaları burada görebilirsiniz: https://github.com/uuid6/new-uuid-encoding-techniques-ietf-d...
UUID v7 zaman damgası, Databend için büyük bir değişimdi. AWS S3’te metadata dosyalarını zaman damgasına göre hızlıca bulmak için kullanıyoruz; bu sayede vacuum benzeri işler çok daha hızlı oldu
PR: https://github.com/datafuselabs/databend/pull/16049
Zamana göre sıralanan UUID’lerin büyük avantajı locality sağlamasıdır. İndekse yeni öğe eklemek çoğu zaman sona ekleme haline gelir ve rastgele eklemeye göre daha ucuz olabilir. Ama contention da artabilir; bu yüzden zaman damgasının önüne biraz rastgele bit koyup sıralı “shard”lar oluşturan hibrit bir yaklaşım da düşünülebilir. Okumalar da çoğu zaman en yeni verilere yoğunlaşır; dolayısıyla yeni verilerin bir arada olması ve cache’e iyi oturması faydalıdır
uuid2'nin amacını anlamak zor. Böyle başka türlerin de olduğunu bilmiyordum; Xandr'a kişisel verilerimin silinmesini talep ederken uuid2'yi ilk kez gördüm: https://news.ycombinator.com/item?id=40913915
Wikipedia'yı okuyunca bile neden bir “evrensel benzersiz tanımlayıcı” yapıp sonra birden çok tür tanımladıklarını, bunların bazılarının neden başlangıçta asıl PC'ye kadar izlenebilir olacak şekilde tasarlandığını pek anlayamıyorum. MAC kodunun bir kısmını katmak uuid2'yi daha rastgeleye mi yaklaştırıyor, yoksa başka bir sebep mi var, merak ediyorum. Gizlilik açısından bakınca, seçilebilecek karakter sayısı çok fazla olan uzun bir tanımlayıcı kullanıp çakışma olasılığını fiilen yok etmek yeterli olmaz mı diye de düşünüyorum
Herhangi iki makine de aynı iki girdi için aynı UID/UUID'yi üretebiliyordu ve tanımlanmış mesajı alan taraf, tanımlayıcıyı tekrar özgün bileşenlerine ayırabiliyordu. Geçici mesajların etiketi olarak tasarlandığı için iki boyut zaman ve donanım kimliğiydi; başlangıçta Apollo seri numarası, daha sonra Ethernet donanım adresi gibi değerler kullanıldı
Karışıklığın büyük kısmının, erken AEGIS uygulamalarında Apollo mühendislerinin dosya sistemi tanımlaması için “canned”, yani statik ve iyi bilinen UID'ler kullanmaya başlamasından kaynaklandığını düşünüyorum. Zamanla UUID'nin genel kullanımı, tekrarın amaçlandığı geçici tanımlayıcılardan, tekrarın önlenmesi gereken canned tanımlayıcılara tamamen kaydı ve iki boyut da rastgelelik ile bir başka rastgeleliğe dönüştü
Tarihçe daha da karmaşık. Microsoft, Windows NT için MSRPC yapmak üzere Apollo'daki kilit isimlerden birini işe aldı ve böylece GUID de ortaya çıktı. GUID'nin alan yerleşimi UUID'den farklıdır ve pek çok kaynağın söylediğinin aksine karma endianness kullanmaz. Microsoft, geçici RPC mesajlarını tanımlayan GUID'lerin yanı sıra COM sınıfları, medya codec'leri ve iyi bilinen tanımlayıcı gerektiren neredeyse her şey için canned GUID kullanmayı sever. Örnek: https://gix.github.io/media-types/
Aynı yorum dizisinde depoma ikinci kez bağlantı verdiğim için kusura bakmayın; ama UUID kütüphanemin README dosyasında bu tarihi toparlamaya başlamıştım ve devam etmem gerekiyor. Apollo 1980'de başladı, Leach/Salz UUID RFC taslağı ise ancak 1998'de çıktı; yani modern standartlarda yer almayan çok fazla ayrıntı var: https://github.com/okeeblow/DistorteD/blob/NEW%E2%80%85SENSA...
UUID v4, belirli konumlara tire koyan bir rastgele bayt üretecinden ibaret. Bunu özellikle kullanmak zorunda değilsiniz; rastgele baytları kendiniz üretip alan tasarrufu sağlayabilirsiniz
Gereksiz tireler ve sürüm bilgisi gibi şeyler de ortadan kalkar
Bu, IPv4 adresinin 32 bitlik bir sayı olması ve “noktayla ayrılmış dört grup” biçiminin onun gösterimlerinden biri olması gibi. UUID'yi bir dize biçimi olarak düşünüyorsanız, UUID hakkındaki en temel kavramı baştan yanlış kurmuşsunuz demektir. Yalnızca rastgele bir tanımlayıcı isteseniz bile, rastgele bir UUID'nin üzerinde “bu kasıtlı olarak rastgele üretildi” diyen küçük bir bayrak biti bulunmasını hoş buluyorum. Bağlamı olmayan tek bir tanımlayıcıyla karşılaştığınızda işe yarar
Farklı üretim yöntemleri arasında ayrı ad alanları oluşturmanın ne kadar faydalı olduğu tartışılabilir ama sıradan bir rastgele sayı üretecinin geçerli bir UUIDv4 üretme olasılığı yalnızca 1/16'dır. Elbette UUID üretecini kendiniz yazmak istiyorsanız, bitleri doğru ayarlamak önemsiz bir ayrıntıdır
Go'da
uuid.New().String()yeterli, amacrypto/randile rastgele veri okuyup bunu base64 veya hex'e çevirmek daha fazla satır ve emek gerektiriyorMAC tabanlı sürümlerin kullanılmamasını öneririm. Teorik olarak v4 ve v7 dışındakilerin hepsi buna girebilir ama en kötüsü v1'dir
v3'te de MD5'in ciddi biçimde kırılmış olması sorunu var
4 dışındaki ayrıntıları bilmiyordum ama gerçekten eksik olan faydalı şeyin, SHA256 verisi ve sayaç kullanan bir yöntem olduğunu düşünüyorum. PBKDF2'ye benzer bir yapı gibi
Gizliliği koruyan türetilmiş bir tanımlayıcı olabilir ve belirli bir UUID'nin belli bir seed'den türetildiğini gevşek biçimde kanıtlamaya da yarayabilir
Bunun dışında muhtemelen daha uzun bir çıktı istemeye başlarsınız
Sadece v7 kullanın
Şimdi güvenlik uzmanı olmayanların “hayır” deme sırası gelecek
Pek çok kullanımda, veriyi yeniden işleseniz bile aynı ID'yi üretebilmek çok faydalı olurdu ama bunu başarmanın standart bir yolunu bilmiyorum