İçeriğe geç

ULID Oluşturucu - Çevrimiçi Benzersiz Sıralanabilir Kimlikler Ücretsiz

Ücretsiz ULID oluşturucu aracı, anında benzersiz, sıralanabilir tanımlayıcılar oluşturur. Veritabanları, API'ler ve dağıtık sistemler için kriptografik olarak güvenli ULID'ler oluşturun.

ULID Oluşturucu

Sonucu görmek için değer girin
Yükleme hesaplayıcısı...
📚

Belgeler

ULID nedir?

ULID (Evrensel Olarak Benzersiz, Sözlük Sırasına Göre Sıralanabilir Tanımlayıcı), bir veritabanındaki kayıtları veya dağıtık sistemdeki bir olayı etiketlemek için kullanılan 26 karakterlik bir koddur. Geçerli zamanı rastgele verilerle birleştirir; bu nedenle alfabetik olarak sıralanan ULID listesi, oluşturulma zamanlarına göre de sıralanmış olur. ULID üreteci, bu kodları oluşturan bir araçtır.

ULID yapısı

ULID, ayraç kullanılmadan art arda yazılan iki bölümden oluşur:

  • Zaman damgası (10 karakter): 1 Ocak 1970 tarihinden (Unix başlangıç zamanı) bu yana geçen milisaniye sayısıdır ve en fazla 48 bit kapsar.
  • Rastgelelik (16 karakter): Aynı milisaniyede oluşturulan iki ULID'nin neredeyse kesinlikle farklı olmasını sağlamak için eklenen 80 bitlik rastgele veridir.

Her iki bölüm de Crockford'un Base32 alfabesi kullanılarak yazılır: 0–9 rakamları ve I, L, O ve U harfleri çıkarılmış A-Z harfleri. Bu dört harf, 0 ve 1 rakamlarıyla veya birbirleriyle karıştırılabileceği için kullanılmaz. Sonuç, kısa, sesli okunması kolay ve doğrudan bir URL'ye yerleştirilebilen güvenli bir dizedir.

ULID nasıl hesaplanır?

ULID üreteci, bir tanımlayıcıyı üç adımda oluşturur.

  1. Geçerli zamanı okuyun: Unix başlangıç zamanından bu yana geçen milisaniye cinsinden zamanı okuyun. Bu, 48 bitlik bir sayıdır.
  2. 80 bitlik rastgele veri oluşturun; bu veri normalde kriptografik açıdan güvenli bir rastgele sayı üretecinden alınır ve 10 rastgele bayt verir.
  3. Her iki bölümü ayrı ayrı kodlayın: Crockford'un Base32 alfabesini kullanın. 48 bitlik zaman damgası 10 karaktere, 80 bitlik rastgele değer ise 16 karaktere dönüşür. Kodlanan iki dize birleştirilerek son 26 karakterlik ULID oluşturulur.

Kodlama, sayının her seferinde 5 bit okunmasıyla yapılır; çünkü her Base32 karakteri 32 olası değerden birini temsil eder (2^5 = 32). On karakter en fazla 50 bit tutabilir; bu da 48 bitlik zaman damgası için yeterlidir. On altı karakter tam olarak 80 bit tutar; bu, geriye hiçbir şey kalmadan rastgelelik bölümüne karşılık gelir.

Çözümlü örnek

Bir ULID üretecinin 1712345678901 zaman damgasında çalıştığını ve [12, 240, 88, 3, 199, 45, 6, 231, 128, 17] rastgele baytlarını aldığını varsayalım.

Adım 1 – zaman damgasını kodlayın. 1712345678901 sayısını art arda 32'ye bölün; her seferinde kalanı alın ve rakamları sondan başa doğru okuyun (bu, standart taban dönüşümüdür). Böylece 10 karakterlik 01HTQW311N dizesi elde edilir.

Adım 2 – rastgeleliği kodlayın. 10 rastgele baytını 80 bitlik bir akışta birleştirin, ardından 5 bitlik gruplar halinde okuyup her 5 bitlik parçayı bir Base32 karakterine dönüştürün. Böylece 16 karakterlik 1KR5G0Y75M3EF00H dizesi elde edilir.

Adım 3 – bölümleri birleştirin. Son ULID şöyledir:

101HTQW311N 1KR5G0Y75M3EF00H
2

boşluk bırakılmadan yazıldığında: 01HTQW311N1KR5G0Y75M3EF00H, toplam 26 karakter.

Bu üreteci kullanma

Üreteç tarayıcıda çalışır. Her ULID, tarayıcının saatinden ve tarayıcının kriptografik rastgele sayı üretecinden alınan 80 yeni rastgele bitten oluşturulur; bu nedenle hiçbir tanımlayıcı sunucuya gönderilmez veya sunucudan alınmaz.

  • ULID sayısı, 1 ile 50 arasında bir tam sayı kabul eder. Varsayılan değer 1'dir.
  • ULID oluştur, yeni bir grup üretir. Sayının değiştirilmesi de yeni bir grup üretir.
  • Bir sonucun yanındaki Kopyala, yalnızca o ULID'yi kopyalar. Birden fazla sonuç gösterildiğinde Tümünü kopyala, listenin tamamını her satırda bir ULID olacak şekilde kopyalar.
  • Sıfırla, sayıyı 1 değerine döndürür ve yeni bir ULID oluşturur.

Sonuçların altında yer alan ULID Yapısı paneli, gruptaki ilk ULID'yi iki bölüme ayırır: ilk 10 karakter (zaman damgası) ve son 16 karakter (rastgelelik).

ULID ve UUID karşılaştırması

ÖzellikULIDUUID (sürüm 4)
Uzunluk26 karakter36 karakter (tirelerle)
Oluşturulma zamanına göre sıralanabilirEvetHayır
KodlamaCrockford Base32Onaltılı
Zaman damgası içerirEvet (48 bit)Hayır
Kaçış karakterlerine gerek olmadan URL'lerde güvenle kullanılabilirEvetEvet

Her iki biçim de merkezi bir otoritenin numara dağıtmasına gerek kalmadan sistemler arasında benzersiz tanımlayıcılar üretmeyi amaçlar. Temel pratik fark sıralamadır: ULID bir zaman damgasıyla başladığı için ULID'leri düz metin olarak sıralamak onları zamana göre de sıralar. Rastgele bir UUID bu özelliğe sahip değildir; çünkü tüm parçaları rastgeledir.

Yaygın Kullanımlar

  • Veritabanı birincil anahtarları: ULID'ler, veritabanının yeni satırları yaklaşık olarak eklenme sırasına göre indekslemesini sağlar; birçok veritabanı motoru bunu tamamen rastgele anahtarlara göre daha verimli işler.
  • Dağıtık sistemler: Ayrı sunucular, merkezi bir sayaçla koordinasyon kurmadan bağımsız olarak ULID üretebilir ve sonuçlar yine de neredeyse kesinlikle benzersiz olur.
  • Olay günlükleri: ULID'ler zamana göre sıralandığı için olay kimliklerinin listesi yaklaşık bir zaman çizelgesi olarak da kullanılabilir.
  • API ve dosya tanımlayıcıları: Sabit uzunluktaki 26 karakterlik, URL'lerde güvenli biçim web adreslerinde ve dosya adlarında sorunsuz çalışır.

İlgili tanımlayıcı biçimleri arasında sıralama için zaman damgasını da kodlayan KSUID ile Twitter ve diğerleri tarafından kullanılan; zaman damgasını, makine tanımlayıcısını ve sayacı birleştiren Snowflake kimlikleri bulunur.

Kod Örnekleri

Aşağıdaki her örnek, ULID belirtiminin açıkladığı şekilde bir ULID oluşturur: 48 bitlik zaman damgasını 10 Crockford Base32 karakteri olarak kodlar, 80 bitlik rastgeleliği 16 karakter daha olarak kodlar ve bunları birleştirir.

JavaScript

1const ENCODING_CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
2
3function encodeULID(time, randomBytes) {
4  // Timestamp: 48 bits -> 10 characters
5  let timestampStr = '';
6  let t = time;
7  for (let i = 0; i < 10; i++) {
8    timestampStr = ENCODING_CHARS[t % 32] + timestampStr;
9    t = Math.floor(t / 32);
10  }
11
12  // Randomness: 80 bits -> 16 characters
13  let result = timestampStr;
14  let bits = 0;
15  let bitCount = 0;
16  for (let i = 0; i < 10; i++) {
17    bits = (bits << 8) | randomBytes[i];
18    bitCount += 8;
19    while (bitCount >= 5) {
20      bitCount -= 5;
21      result += ENCODING_CHARS[(bits >> bitCount) & 0x1f];
22    }
23  }
24  return result;
25}
26
27function generateULID() {
28  const randomBytes = crypto.getRandomValues(new Uint8Array(10));
29  return encodeULID(Date.now(), randomBytes);
30}
31
32console.log(generateULID());
33

Python

1import os
2import time
3
4ENCODING_CHARS = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
5
6def encode_ulid(time_ms, random_bytes):
7    # Timestamp: 48 bits -> 10 characters
8    chars = []
9    t = time_ms
10    for _ in range(10):
11        chars.append(ENCODING_CHARS[t % 32])
12        t //= 32
13    timestamp_part = "".join(reversed(chars))
14
15    # Randomness: 80 bits -> 16 characters
16    bits = 0
17    bit_count = 0
18    random_part = []
19    for byte in random_bytes:
20        bits = (bits << 8) | byte
21        bit_count += 8
22        while bit_count >= 5:
23            bit_count -= 5
24            random_part.append(ENCODING_CHARS[(bits >> bit_count) & 0x1F])
25
26    return timestamp_part + "".join(random_part)
27
28def generate_ulid():
29    return encode_ulid(int(time.time() * 1000), os.urandom(10))
30
31print(generate_ulid())
32

Java

1import java.security.SecureRandom;
2import java.time.Instant;
3
4public class ULIDGenerator {
5    private static final SecureRandom random = new SecureRandom();
6    private static final char[] ENCODING_CHARS =
7        "0123456789ABCDEFGHJKMNPQRSTVWXYZ".toCharArray();
8
9    public static String generateULID() {
10        long timestamp = Instant.now().toEpochMilli();
11        byte[] randomBytes = new byte[10];
12        random.nextBytes(randomBytes);
13
14        // Timestamp: 48 bits -> 10 characters
15        char[] timestampChars = new char[10];
16        long t = timestamp;
17        for (int i = 9; i >= 0; i--) {
18            timestampChars[i] = ENCODING_CHARS[(int) (t % 32)];
19            t /= 32;
20        }
21
22        // Randomness: 80 bits -> 16 characters
23        StringBuilder result = new StringBuilder(new String(timestampChars));
24        long bits = 0;
25        int bitCount = 0;
26        for (byte b : randomBytes) {
27            bits = (bits << 8) | (b & 0xFF);
28            bitCount += 8;
29            while (bitCount >= 5) {
30                bitCount -= 5;
31                result.append(ENCODING_CHARS[(int) ((bits >> bitCount) & 0x1F)]);
32            }
33        }
34        return result.toString();
35    }
36
37    public static void main(String[] args) {
38        System.out.println(generateULID());
39    }
40}
41

Sık sorulan sorular

ULID ne için kullanılır? ULID; oluşturulma zamanına göre sıralamanın da yararlı olduğu durumlarda bir veritabanı satırı, API kaynağı veya günlüğe kaydedilmiş olay için benzersiz tanımlayıcı olarak kullanılır.

ULID ne kadar uzunluktadır? ULID her zaman 26 karakter uzunluğundadır: zaman damgası için 10 karakter ve rastgele bölüm için 16 karakter.

ULID hangi kodlamayı kullanır? ULID, 0–9 rakamlarından ve diğer karakterlerle karıştırılmasını önlemek için I, L, O ve U harfleri çıkarılmış A-Z harflerinden oluşan Crockford'un Base32 alfabesini kullanır.

ULID ile UUID arasındaki fark nedir? ULID oluşturulma zamanına göre sıralanır ve 26 karakter uzunluğundadır. Rastgele bir (sürüm 4) UUID zamana göre sıralanmaz ve tireler dahil 36 karakter uzunluğundadır.

İki ULID'nin çakışma olasılığı nedir? 80 bitlik rastgelelik, çakışmaları son derece olasılık dışı kılar. Herhangi iki ULID'nin eşleşme olasılığının %50 olması için aynı milisaniye içinde yaklaşık 1,3 trilyon ULID üretilmesi gerekir.

ULID'ler internet bağlantısı olmadan oluşturulabilir mi? Evet. ULID için yalnızca yerel saat ve bir rastgele sayı üreteci gerekir; bu nedenle tamamen çevrimdışı olarak oluşturulabilir.

Kaynaklar

  1. "ULID Specification." GitHub, https://github.com/ulid/spec.
  2. "Crockford's Base32 Encoding." http://www.crockford.com/base32.html.