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

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.

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