UUID Versiyonları ve Varyantları
Bir önceki yazımızda UUID hakkında daha temel bilgiler vermiştik. Avantajlarından ve dezavantajlarından bahsetmiştik.
Bu yazıda UUID versiyon ve varyant değerlerine değineceğiz ve bazı versiyonlar için UUID değerleri üreteceğiz.
UUID Formatı
32 hexadecimal karakterden oluşan, 4 tire ile ayrılmış 8-4-4-4-12 formatında, 5 gruplu, toplamda 36 karakterden oluşan karakter dizisidir.
9e7d1500-fdb2-4d79-8353-ae7f9baee8cf
UUID Versiyon ve Varyant Değerlerini Anlamak
UUID değerinin hangi versiyondan ve hangi varyant değerinden üretildiğini anlamak mümkündür;
xxxxxxxx-xxxx-Xxxx-Yxxx-xxxxxxxxxxxx
X (Versiyon)
- UUID değerinin hangi versiyon olduğunu belirtir.
- Hexadecimal değeri direkt versiyon değerini gösterir.
Y (Varyant)
- Varyant değerini belirtir.
- Varyant değerini anlamak için hexadecimal değerinin karşılık geldiği aralığa bakmak gerekir. (Aşağıdaki tabloda bu aralıklar gösterilmiştir)
UUID Varyant (Variant) Değeri
Varyant değeri UUID değerinin kodlama (encoding) ve formatını belirler. RFC 4122' e göre 1 ile 3 bit uzunluğunda dört varyant tanımı vardır. Varyant 1 en sık kullanılandır.
Binary | Hex Digit | Varyant |
---|---|---|
0xxx | 0 - 7 | Varyant 0 (1 bit) - NCS (Network Computing System) için geriye dönük uyumluluğa ayrılmıştır |
10xx | 8 - b | Varyant 1 (2 bit) - RFC 4122/DCE 1.1 UUIDs |
110x | c - d | Varyant 2 (3 bit) - Reserved, Microsoft'un geriye dönük uyumluluğu için ayrılmıştır |
111x | e - f | Varyant 3 - Gelecekteki bir tanım için ayrılmıştır. |
Birkaç UUID Örneğine bakalım. Versiyon ve Varyant Değerlerini inceleyelim;
2f45493b-9360-11ec-acae-4f4fe1145b2c —> Versiyon 1, Varyant 1
f385a913-2af7-4020-94d3-d4579f47d9e3 —> Versiyon 4, Varyant 1
3aea5a63-f50b-5bf2-93b8-7e99df390f4d —> Versiyon 5, Varyant 1
UUID Versiyonları
Versiyon 1
- Sürüm-1, UUID'yi oluşturan bilgisayar için geçerli mevcut zamanı (timestamp) değeri ve MAC adresini temel alır.
- İlgili tarih başlangıç değeri, 15 Ekim 1582'den itibaren 100 nanosaniye cinsinden baz alınmıştır.
- Eğer mac adres (node) ve timestamp değerini biliniyorsa tahmin edilmesi ve tekrar üretilmesi kolay olacaktır.
- İki farklı makinada üretilen UUID değerleri Mac adres (node) değerinden dolayı duplicate olamaz.
Versiyon 1 UUID Oluşturma
PostgreDB
-
SELECT uuid_generate_v1();
Linux Terminal
uuidgen -t
komutuyla arka arkaya bu scripti çalıştıralım;
Üretilen UUID değerleri;
"2fce3ee4-95d3-11ec-9848-4f4fe1145b2c"
"30a7b624-95d3-11ec-9848-4f4fe1145b2c" olacaktır.
İlk 8 basamak hariç tüm değerler aynı ve son 12 basamağı node değeri yani mac adres değerini yansıtmaktadır.
Bilgisayarın zamanını 2 ileriye alıp tekrar ürettiğimizde;SELECT uuid_generate_v1();
veya uuidgen -t
"86cda5ca-9765-11ec-9848-4f4fe1145b2c" değerini üretecektir.
Bilgisayar zamanını birkaç yıl ileriye alalım ve tekrar çalıştıralım;
SELECT uuid_generate_v1();
veya uuidgen -t
"4b5bd632-70b2-11f4-9848-4f4fe1145b2c"
Görülebileceği üzere değerler değişiyor. Buradaki UUID düzenin oluşumu için aşağıdaki tablo incelenebilir.
Not: Versiyon 1'de UUID değerinin son 12 hexadecimal basamağı node değerinden yani varsayılan olarak mac adresinden oluşturulur. Decode edilerek bu değer bulunabilir. Buna çözüm olarak versiyon 1 implementasyonlarında mac adres değeri yerine rastgele node değerleri tercih edilebiliyor.
İsim | Uzunluk (Length) (bytes) | Uzunluk (Length) (hex digits) | Uzunluk (bits) | İçerik |
---|---|---|---|---|
time_low | 4 | 8 | 32 | zamanın düşük 32 bitini veren tam sayı (the low 32 bits of the time) |
time_mid | 2 | 4 | 16 | zamanın orta 16 bitini veren tam sayı (the middle 16 bits of the time) |
time_hi_and_version | 2 | 4 | 16 | En önemli bit (MSB) 4-bit "versiyon" , ardından yüksek zaman değerinden gelen 12 bits (the high 12 bits of the time) |
clock_seq_hi_and_res clock_seq_low | 2 | 4 | 16 | 1 ile 3-bit "varyant" - ardından gelen 13 ile 15-bit saat sırası (the 13 to 15-bit clock sequence) |
node | 6 | 12 | 48 | 48 bit node( Varsayılanda Mac Adres Değeri) (the 48-bit node id) |
Toplam | 16 | 32 | 128 |
Timestamp UUID Oluşturulma Düzeni
Versiyon 2
- Versiyon 1'de olduğu gibi mevcut zaman (timestamp) ve Mac adres bilgisine göre UUID değeri üretir
- RFC dokümanı bu versiyon için detay vermediğinden implementasyonu ve kullanımı pek yaygın değildir.
Versiyon 3
- Versiyon 3'de namespace ve name değerleriyle MD5 (128 bit) Hash algoritması kullanılarak UUID değeri üretilir.
- Name ve namespace değerleri aynı verilirse, aynı UUID değerini üretecektir. Aynı değerle UUID üretme ihtiyacında bu versiyon tercih edilebilir.
Not : Versiyon 3 ile UUID oluşturma örneğini versiyon 5'in sonunda göstereceğim.
Versiyon 4
- Versiyon 4, rastgele değerlere dayalı bir UUID değeri oluşturur.
- Versiyon 4 - Varyant 1 (2 bit) tipinde versiyon numarası (4 bit) sabit olacağından, toplamda 122 bit random değerle üretilecektir. Bu da 2122 yani 5.3 x 1036 adet eşsiz (unique) id (UUID) alabilir.
- Versiyon 4 - Varyant 2 (3 bit) toplamda 2121 random değer alabileceğinden, Versiyon 4 - Varyant 1 tipine göre yarısı kadar eşsiz id değeri (UUID) alabilir.
- Mac adresi, zaman değeri veya name/namespace değerlerine göre üretilmediği için tahmin etmesi ve tekrar etmesi bir hayli zordur.
Versiyon 4 ile UUID oluşturma;
PostgreDB
SELECT uuid_generate_v4();
Linux Terminalde
uuidgen -r
"34779908-2848-4b2d-939d-df321b66a82b"
"8d9ee101-6229-4c88-be76-9502e6ac347a" UUID değerleri üretilecektir
Versiyon 5
- Versiyon 3'de olduğu gibi name ve namespace değerlerini kullanarak UUID değerini üretir. Farkı ise MD5 yerine, SHA-1 (160 bit) hash algoritmasıyla UUID değerini üretir.
- Yine versiyon 3 de olduğu gibi, Name ve namespace değerleri aynı verilirse, aynı UUID değerini üretecektir. Aynı değerle UUID üretme ihtiyacında bu versiyon tercih edilebilir.
- SHA-1 algoritmasını kullandığı için Versiyon 3'e göre daha güvenlidir.
Namespace ve Name Değerleri
Versiyon 3 ve versiyon 5 de bahsettiğimiz namespace ve name değerleri;
Namespace:
- Temelde bir UUID değeridir. Herhangi bir UUID değeri olabilir.
- Standart implementasyonlarda önceden tanımlanmış olan namespace UUID değerleri kullanılır.
- Bu namespace UUID değerleri, DNS, URL, OID veya x500 olablir.
Name:
- Herhangi bir değer olabilir.
Namespace UUID değerleri
RFC 4122 dokümanına göre, Versiyon 3 ve 5'de bahsettiğimiz namespace alan değerlerinin UUID değerleri şöyledir;
- 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
Not: Versiyon 3 veya 5 ile oluşturulan UUID değerinden name veya namespace değerleri decoding yapılarak tespit edilemez.
Versiyon 3 ve 5 için UUID Oluşturma
Versiyon 3
Linux Terminal
uuidgen -m --namespace 6ba7b811-9dad-11d1-80b4-00c04fd430c8 --name https://volkandogan.net
PostgreDB
select uuid_generate_v3('6ba7b811-9dad-11d1-80b4-00c04fd430c8', 'https://volkandogan.net');
- Namespace değerini, RFC dokümanında tanımlı olan URL UUID değerini verdik
- Name değerini de "https://volkandogan.net" verelim
- Oluşan UUID değeri: "bfcc1da2-9196-3441-ae15-a311819c3f09" olacaktır.
Not: Aynı namespace ve name değeriyle tekrar oluşturursak yine aynı UUID değerini üretecektir.
Bu sefer "name" değerini farklı verelim;
Linux Terminal
uuidgen -m --namespace 6ba7b811-9dad-11d1-80b4-00c04fd430c8 --name https://volkandogan.net/home
PostgreDB
select uuid_generate_v3('6ba7b811-9dad-11d1-80b4-00c04fd430c8', 'https://volkandogan.net/home');
Oluşan UUID değeri: "9b3c7828-2d27-3ff1-bffe-c1735d029086" olacaktır.
Versiyon 5 ile UUID Oluşturma
Postgre DB
select uuid_generate_v5('6ba7b811-9dad-11d1-80b4-00c04fd430c8', 'https://volkandogan.net');
Linux Terminal
uuidgen -s --namespace 6ba7b811-9dad-11d1-80b4-00c04fd430c8 --name https://volkandogan.net
komutu ile ;
- Namespace değerini, NameSpace_URL UUID değeriyle
- Name değerini de "https://volkandogan.net" ile oluşturduğumuzda;
- Üretilen UUID değeri : "dd3a9e4f-518a-510d-8e35-581198e605c1" olacaktır.
Not: Versiyon 3'de olduğu gibi aynı değerlerle oluşturmak istediğimizde yine aynı UUID değerini üretecek.
Name değerini farklı verelim;
Postgre DB
select uuid_generate_v5('6ba7b811-9dad-11d1-80b4-00c04fd430c8', 'https://volkandogan.net/home');
Linux Terminal
uuidgen -s --namespace 6ba7b811-9dad-11d1-80b4-00c04fd430c8 --name https://volkandogan.net/home
Oluşan UUID değeri: "c5949a08-c739-5099-99c4-ccb5ee00ccc2" olacaktır.
Nil UUID
Özel bir değer olan "nil" UUID, tüm bits yani tüm değerleri sıfıra ayarlanmış UUID değeridir.
PostgreDB - select uuid_nil();
scriptini çalıştırırsak.
- 00000000-0000-0000-0000-000000000000
Sonuç;
Bu yazımızda UUID varyant ve versiyon değerlerinin neler olduğunu ve nasıl anlaşılacağını görmüş olduk. Ayrıca bazı UUID versiyonları için birkaç UUID üretmiş ve bazı detaylara değinmiş olduk.
Yararlandığım Kaynaklar;
https://en.wikipedia.org/wiki/Universally_unique_identifier
https://datatracker.ietf.org/doc/html/rfc4122
https://www.postgresql.org/docs/9.4/uuid-ossp.html
https://man7.org/linux/man-pages/man1/uuidgen.1.html