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

PostgreDB

  1. Namespace değerini, RFC dokümanında tanımlı olan URL UUID değerini verdik
  2. Name değerini de "https://volkandogan.net" verelim
  3. 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

PostgreDB

Oluşan UUID değeri: "9b3c7828-2d27-3ff1-bffe-c1735d029086" olacaktır.

Versiyon 5 ile UUID Oluşturma

Postgre DB

Linux Terminal

  1. Namespace değerini, NameSpace_URL UUID değeriyle
  2. Name değerini de "https://volkandogan.net" ile oluşturduğumuzda;
  3. Ü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

Linux Terminal

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