UUID Versiyonları ve Varyantları
1-Giriş
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.
2- 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
3- 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
3.1 X (Versiyon)
- UUID değerinin hangi versiyon olduğunu belirtir.
- Hexadecimal değeri direkt versiyon değerini gösterir.
3.2 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)
4- 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
5 - 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
5.2 - 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.
5.3 - 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.
5.4 - 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
5.5 - 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ğerlerinden, name veya namespace değerleri decoding yapılarak tespit edilemez.
5.6 - 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.
6- 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