Başkasının oluşturduğu hiçbir tanımlayıcıyla çakışmayacak, daha önce adını bile duymadığınız bir makinede, kimseden izin istemeden oluşturabileceğiniz bir tanımlayıcıya mı ihtiyacınız var? İşte UUID'nin görevi tam olarak budur. UUID, tanıdık 8-4-4-4-12 düzeninde 36 karakter olarak yazılan 128 bitlik bir sayıdır ve tüm tasarımı, kimin hangi değeri alacağını koordine eden hiçbir sistem olmamasına rağmen, iki UUID'nin asla aynı olmamasına dayanır. Bu ücretsiz oluşturucu, onları tarayıcınızda üretir: Sürüm alanından bir sürüm seçin, Adet alanında kaç tane istediğinizi belirtin ve Oluştur düğmesine basın. Sayfa varsayılan olarak çoğu projenin tercih ettiği tek bir v4 ile açılır, bu sayede ilk tanımlayıcınıza sadece bir tık uzaktasınız.
Her tanımlayıcı, tarayıcınız tarafından Web Crypto API aracılığıyla oluşturulur. Sürüm 4, tarayıcının sunduğu yerlerde crypto.randomUUID(), aksi durumlarda crypto.getRandomValues() kullanır — bu, Math.random() gibi JavaScript'in sözde rastgele (pseudo-random) fonksiyonları yerine, kriptografik olarak güçlü bir rastgelelik kaynağıdır. Sürüm 7, en başa 48 bitlik milisaniye zaman damgasını yerleştirir, ardından aynı milisaniye içinde artan 12 bitlik bir sayaç ve 62 rastgele bit ekler. Bu, RFC 9562'de açıklanan sıralama yöntemidir; bin adetlik bir partinin karışık değil de sırayla çıkmasının nedeni de işte bu sayaçtır. Sürüm 1, zaman damgasını çoklu yayın (multicast) biti ayarlanmış rastgele bir düğüm tanımlayıcısı ile birleştirir, bu nedenle 1990'lardaki orijinal uygulamaların yaptığı gibi asla ağ kartınızın (MAC) adresini taşımaz. Sürüm 3 ve 5 ise hiçbir şekilde rastgele değildir: sırasıyla MD5 ve SHA-1 kullanarak bir ad alanını bir ad ile birleştirip özetini (hash) çıkarırlar ve bu karma işlemi de yine cihazınızda gerçekleşir. Bir sunucuya hiçbir şey gönderilmez, hiçbir şey günlüğe kaydedilmez (loglanmaz) ve sayfa yüklendikten sonra bağlantı kapalıyken bile çalışmaya devam eder.
Sürüm, geri kalan her şeyi belirleyen alandır. Sürüm 4, 122 rastgele bit olup hiçbir yapıya sahip değildir — varsayılan seçenektir ve bir tanımlayıcının yalnızca benzersiz olması gerektiğinde doğru cevaptır. Sürüm 7, 62 rastgele biti korur, ancak başlangıcına oluşturulduğu zamanı ekler, böylece elde edilen kümeler oluşturulma sırasına göre dizilebilir; tanımlayıcının bir veritabanı anahtarı olacağı durumlarda başvurulması gereken sürüm de budur. Sürüm 1, zaman tabanlı orijinal şemadır ve bunu hâlâ talep eden sistemler için burada tutulmaktadır. Sürüm 3 ve 5 birbirine benzeyen özel bir çifttir: bunlar deterministiktir, yani aynı girdiler her zaman aynı tanımlayıcıyı üretir. İki ek alana ihtiyaç duyarlar — standart DNS, URL, OID ve X.500 alanlarından biri veya kendinize ait Özel ad alanı (UUID) olabilen Ad alanı ile, tanımlanacak metin (string) olan Ad. v5'e URL ad alanını ve https://example.com/a değerini verdiğinizde; bugün, yarın veya başka birinin makinesinde aynı UUID'yi elde edersiniz. Bu nedenle, v3 veya v5 seçildiğinde Adet alanı gizlenir: deterministik bir değerin bin kopyası, sadece aynı deterministik değerin bin kopyasından ibaret olurdu. Diğer tüm sürümler için Adet 1'den 1000'e kadar çalışır.
Dört anahtar, altındaki 128 biti değiştirmeden çıktının şeklini değiştirir. Büyük harfler onaltılık basamakları majüskül olarak yazdırır, Tire olmadan bazı sütunların ve dosya adlarının tercih ettiği 32 karakterlik kompakt formu verir ve Süslü parantez değeri { } içine alır — bu, Windows ve .NET dünyasının GUID adını verdiği formattır. Gelişmiş Seçenekler altındaki urn:uuid:, onu resmi bir URN yapan ön eki ekler; açık olduğu sürece Süslü parantez ve Tire olmadan seçeneklerini devre dışı bırakır, çünkü standart yalnızca tek bir URN biçimine izin verir ve bu da tireli kanonik biçimdir. Kopyalama biçimi, bir partiyi aldığınızda nasıl birleştirileceğine karar verir: her satıra bir tane, virgüllerle ayrılmış veya doğrudan koddaki bir diziye yapıştırabilmeniz için her değer tırnak içine alınıp sonuna virgül konmuş şekilde. Sonucun altında rastgeleliği bit cinsinden raporlayan bir satır yer alır — v4 için 122, v7 için 62 — ve v7 için, değerin içindeki zamanın üstü kapalı olmak yerine görünür olması adına, partideki ilk tanımlayıcıya kodlanmış zaman damgasını gösterir. Tümünü kopyala ve Dosyaya kaydet işlemlerinin her ikisi de Kopyalama biçimi seçimine uyar. Geçmiş, kendi tarayıcınızdaki son 10 partinizi saklar: birini geri getirmek için tıklayın, tek bir girdiyi kopyalayın veya silin ya da tümünü temizleyin. Temizle sonucu boşaltır ancak ayarlarınızı olduğu gibi bırakır. Ayrıca 50 tanımlayıcıyı geçtiğinde, liste elli satır yerine kaydırılabilir tek bir bloğa dönüşür.
Bu sayfadaki en çok sonuç doğuran şey veritabanı birincil anahtarı (primary key) olarak v4 ile v7 arasındaki farktır ve bu bir zevk meselesi değildir. Veritabanı indeksleri (B-tree gibi) sıralı tutulan ağaçlardır ve yeni bir anahtarın bu sıranın neresine düşeceği, ekleme (insert) işleminin ne kadar işe mal olacağını belirler. Bir v4 anahtarı rastgeledir, bu yüzden art arda gelen eklemeler indeksin birbiriyle ilgisiz köşelerine düşer: dolu olan sayfalar bölünür (page split), veritabanının bellekte tuttuğu ağaç kısımları nadiren bir sonraki eklemenin ihtiyaç duyduğu kısımlardır ve sonuç olarak indeks, işaret ettiği satırların hak ettiğinden daha büyük ve daha parçalanmış hale gelir. Bir v7 anahtarı mevcut milisaniye ile başlar, bu nedenle art arda gelen eklemeler ağacın sağ kenarında yan yana yerleşir. Bu, otomatik artan (auto-increment) bir tam sayının ürettiği kalıptır ve indeks yapılarının etrafına inşa edildiği kalıptır. Bütün takas şudur: v7, ardışık bir anahtarın ekleme davranışını size sunarken, ilk etapta UUID'leri seçmenize neden olan "herhangi biri bir sunucuya sormadan oluşturabilir" özelliğini de korur. Bunun bedeli, oluşturulma zamanının artık tanımlayıcının içinden okunabilir olmasıdır ve bunun önemli olup olmadığı, format hakkında değil, verileriniz hakkında bir sorudur.
Hiçbir şey bir UUID'nin benzersizliğini asla kontrol etmez; boyutu tek garantisidir. Herhangi bir kayıt defteri (registry), sunucu gidiş-dönüşü veya arama (lookup) yoktur — bir oluşturucu bir sayı üretir ve size teslim eder, ikisinin çakışmamasının nedeni ise basitçe 2^122 (yaklaşık 5,3 undesilyon) olası v4 değerinin bulunmasıdır. Doğum günü paradoksu (birthday problem) bunu boyutlandırmanın en dürüst yoludur: herhangi iki tanesinin eşleşme ihtimalinin eşit (%50) olması için yaklaşık 2,7 kentilyon tanımlayıcıya ihtiyacınız vardır, ki bu da 86 yıl boyunca her saniye bir milyar yeni UUID anlamına gelir. Bunun ne vaat edip ne etmediği konusunda kesin olmakta fayda var. Bu aritmetik değil istatistiksel bir garantidir ve yalnızca altındaki rastgelelik gerçek olduğu sürece geçerlidir — kötü bir çekirdekle (seed) oluşturulmuş bir üreteç veya entropi havuzuyla birlikte kopyalanmış bir sanal makine, bunu formatın algılayamayacağı şekilde bozar. Sürüm 7 soruyu daha da daraltır: sayaç zar atmak yerine sürekli arttığı için, tek bir milisaniye içinde bir oluşturucu kendini kesinlikle tekrarlayamaz ve bağımsız oluşturucular arasında işi 62 rastgele bit yapar.
Bir UUID bir tanımlayıcıdır, bir parola değildir. Sürüm 4 öngörülemezdir ve bu durum insanları onu bir sır gibi (parola sıfırlama bağlantısı, tahmin edilemeyen bir URL, oturum belirteci veya bir API anahtarı) kullanmaya teşvik eder. Öngörülemezlik gerçektir, ancak gizlilik bir değerin nasıl işlendiğinin bir özelliğidir ve tanımlayıcılar tasarımları gereği dikkatsizce ele alınırlar: tarayıcı geçmişine, sunucu günlüklerine, referans başlıklarına (referrer) ve analiz araçlarına düşen URL'lerde yer alırlar ve sohbet mesajlarına yapıştırılırlar. Diğer sürümler çok daha kötü adaylardır. Sürüm 1 ve sürüm 7'nin her ikisi de oluşturulma anını kodlar, bu nedenle elinde bunlardan biri olan herhangi biri kabaca ne zaman yapıldığını bilir ve onunla aynı anda yapılan her şeyin etrafındaki çemberi daraltabilir. Sürüm 3 ve 5 ise kasten deterministiktir: Bir e-posta adresinin v5 UUID'si, özetlenmiş (hashlenmiş) bir sır değildir, aynı adrese sahip herkesin bir saniye içinde hesaplayabileceği bir değerdir. Bir şeyi adlandırmak için bir UUID kullanın. Değerin bilinmemesi gerektiği durumlarda bir parola oluşturucu veya sırlar (secrets) için oluşturulmuş bir kütüphaneden bir belirteç (token) kullanın.
Neden bu UUID oluşturucuyu seçmelisiniz?
- Sadece tarayıcıda üretim: tanımlayıcılar cihazınızda üretilir ve asla hiçbir yere gönderilmez
- Web Crypto API rastgeleliği: kriptografik olarak güvenlidir, standart Math.random() değil
- Beş sürüm tek bir yerde: araç değiştirmeden v1, v3, v4, v5 ve v7
- Gerçekten sıralı v7: RFC 9562'de açıklandığı gibi milisaniye içinde çalışan bir sayaç
- Dört standart ad alanı veya kendinize ait bir alan ile deterministik v3 ve v5
- 50'yi geçtikten sonra kompakt, kaydırılabilir bir liste ile tek seferde 1000'e kadar
- Tüm yaygın şekiller: tireli, çıplak, büyük harfli, süslü parantezli veya urn:uuid: URN formunda
- Satırlar, virgüller veya doğrudan koda yapıştırılacak alıntılanmış (tırnaklı) değerler olarak kopyalama
- Sınırsız ve ücretsiz: kayıt yok, kullanım limiti yok, sunucularımızda hiçbir şey yok
UUID'ler, adın boş olduğunu hiçbir sistem onaylayamadan önce bir şeye ad verilmesi gereken her yerde ortaya çıkarlar. Uygulama kodu, eklemek üzere olduğu satırlar için onları üretir; böylece nesne, veritabanına henüz ulaşmadan önce bir kimliğe sahip olur ve yazma işlemi devam ederken bir istemci ona referans verebilir. Dağıtık sistemler onlara daha da fazla yaslanır: tek bir tabloya yazan birkaç hizmet, bir uçakta çevrimdışı kayıt oluşturan bir mobil istemci, daha önce işlediği mesajı tanıması gereken bir kuyruk (queue) — bunların hiçbiri paylaşılan bir sayaç için sırasını bekleyemez. Sürüm 5, zaten sahip olduğunuz bir şeyden türetilen istikrarlı bir tanımlayıcı şeklindeki farklı bir ihtiyacı karşılar: aynı belge, aynı URL veya aynı hesap her zaman aynı UUID ile eşleşir, böylece bir içe aktarma işlemi hiçbir şeyi kopyalamadan (duplike etmeden) iki kez çalıştırılabilir. Başka yerlerde ise basitçe bir sistemin talep ettiği format olurlar — günlükler ve izler (traces) arasına yerleştirilmiş bir korelasyon tanımlayıcısı, bin kullanıcıdan gelen yüklemeler tek bir depolama alanına (bucket) düştüğünde çakışmayacak bir dosya adı, bir Windows kayıt defteri anahtarı (registry key), gerçek veriler gibi görünmesi gereken bir test verisi.
Bilinmesi gereken birkaç dürüst sınır vardır. Bir parti, bir sürüm demektir: Sürüm alanındaki değer o partideki her şey için geçerlidir, bu nedenle bir grup v4 ve bir grup v7 iki ayrı partidir. Bu bir oluşturucudur, bir denetleyici değil — bu sayfa, bir UUID'yi yapıştırıp onun sürümünü veya zaman damgasını okuyabileceğiniz bir yer değildir. Dosyaya kaydet seçeneği, CSV veya JSON yerine düz bir metin dosyası yazar. Sürüm 7, bir kusurdan ziyade gerçek bir takas olarak ne zaman oluşturulduğunu milisaniyesine kadar açıkça gösterir ve sürüm 1 de zamanı aynı şekilde sızdırır; eğer bu durum verileriniz için bir sorunsa, sürüm 4 hiç kimseye hiçbir şey söylemeyen sürümdür. Standartta yer alan iki özel değer sürüm değildir ve bu nedenle Sürüm seçeneklerinde bulunmazlar, ancak buradan kopyalayabilirsiniz: nil UUID olan 00000000-0000-0000-0000-000000000000 ve max UUID olan ffffffff-ffff-ffff-ffff-ffffffffffff. Bu sayfadaki her şey, 2024 yılında RFC 4122'nin yerini alan spesifikasyon olan RFC 9562'yi takip eder, bu nedenle çıktı, UUID'leri işleyebilen herhangi bir kütüphane, veritabanı veya API tarafından kabul edilir. Bu sınırlar dahilinde garanti güçlüdür: her tanımlayıcı standarta uygun olarak, kendi makinenizde, kriptografik olarak güvenli rastgelelikten üretilir ve bunu sizden başka hiç kimse asla görmez.