Lewati ke konten

Generator ULID - Buat ID Unik yang Dapat Diurutkan Secara Daring Gratis

Alat generator ULID gratis membuat pengidentifikasi unik dan dapat diurutkan secara instan. Hasilkan ULID yang aman secara kriptografis untuk basis data, API & sistem terdistribusi secara daring.

Generator ULID

Masukkan nilai untuk melihat hasil
Kalkulator pemuatan...
📚

Dokumentasi

Apa Itu ULID?

ULID (Universally Unique Lexicographically Sortable Identifier atau Pengidentifikasi yang Dapat Diurutkan Secara Leksikografis dan Unik Secara Universal) adalah kode sepanjang 26 karakter yang digunakan untuk memberi label pada catatan dalam basis data atau suatu peristiwa dalam sistem terdistribusi. Kode ini menggabungkan waktu saat ini dengan data acak, sehingga daftar ULID yang diurutkan secara alfabetis pada akhirnya terurut berdasarkan waktu pembuatannya. Generator ULID adalah alat yang menghasilkan kode-kode ini.

Struktur ULID

ULID memiliki dua bagian, yang ditulis berurutan tanpa pemisah:

  • Stempel waktu (10 karakter): jumlah milidetik sejak 1 Januari 1970 (epoch Unix), yang mencakup hingga 48 bit.
  • Keacakan (16 karakter): 80 bit data acak, ditambahkan agar dua ULID yang dibuat pada milidetik yang sama hampir pasti tetap berbeda.

Kedua bagian ditulis menggunakan alfabet Base32 Crockford: digit 0–9 dan huruf A-Z, tanpa huruf I, L, O, dan U. Keempat huruf tersebut dihilangkan karena dapat tertukar dengan digit 0 dan 1, atau satu sama lain. Hasilnya adalah string yang pendek, mudah dibaca keras-keras, dan aman ditempatkan langsung dalam URL.

Cara Menghitung ULID

Generator ULID membentuk pengidentifikasi dalam tiga langkah.

  1. Baca waktu saat ini dalam milidetik sejak epoch Unix. Ini adalah bilangan 48 bit.
  2. Hasilkan 80 bit data acak, biasanya dari generator bilangan acak yang aman secara kriptografis, sehingga menghasilkan 10 byte acak.
  3. Enkode kedua bagian secara terpisah menggunakan alfabet Base32 Crockford: stempel waktu 48 bit menjadi 10 karakter, dan nilai acak 80 bit menjadi 16 karakter. Kedua string yang telah dienkode digabungkan untuk membentuk ULID akhir sepanjang 26 karakter.

Pengenkodean dilakukan dengan membaca bilangan sebanyak 5 bit setiap kali, karena setiap karakter Base32 mewakili salah satu dari 32 kemungkinan nilai (2^5 = 32). Sepuluh karakter dapat memuat hingga 50 bit, yang cukup untuk stempel waktu 48 bit. Enam belas karakter memuat tepat 80 bit, sesuai dengan bagian keacakan tanpa sisa.

Contoh perhitungan

Misalkan generator ULID berjalan pada stempel waktu 1712345678901 (milidetik sejak epoch) dan mengambil byte acak [12, 240, 88, 3, 199, 45, 6, 231, 128, 17].

Langkah 1 – enkode stempel waktu. Bagi 1712345678901 berulang kali dengan 32, ambil sisanya setiap kali, lalu baca digit dari yang terakhir ke yang pertama (ini adalah konversi basis standar). Hasilnya adalah string sepanjang 10 karakter, yaitu 01HTQW311N.

Langkah 2 – enkode keacakan. Kemas 10 byte acak ke dalam aliran 80 bit, lalu baca 5 bit setiap kali dan ubah setiap potongan 5 bit menjadi karakter Base32. Hasilnya adalah string sepanjang 16 karakter, yaitu 1KR5G0Y75M3EF00H.

Langkah 3 – gabungkan bagian-bagian tersebut. ULID akhirnya adalah:

101HTQW311N 1KR5G0Y75M3EF00H
2

ditulis tanpa spasi: 01HTQW311N1KR5G0Y75M3EF00H, dengan total 26 karakter.

Menggunakan Generator Ini

Generator berjalan di browser. Setiap ULID dibentuk dari jam browser dan 80 bit acak baru yang diambil dari generator bilangan acak kriptografis browser, sehingga tidak ada pengidentifikasi yang dikirim ke atau diambil dari server.

  • Jumlah ULID menerima bilangan bulat dari 1 hingga 50. Nilai bawaannya adalah 1.
  • Hasilkan ULID menghasilkan sekumpulan ULID baru. Mengubah jumlahnya juga menghasilkan sekumpulan ULID baru.
  • Salin pada suatu hasil menyalin satu ULID tersebut. Jika lebih dari satu ULID ditampilkan, Salin semua menyalin seluruh daftar, satu ULID per baris.
  • Atur ulang mengembalikan jumlah ke 1 dan menghasilkan satu ULID baru.

Di bawah hasil, panel Struktur ULID membagi ULID pertama dalam kumpulan menjadi dua bagian: 10 karakter pertama (stempel waktu) dan 16 karakter terakhir (keacakan).

ULID vs UUID

FiturULIDUUID (versi 4)
Panjang26 karakter36 karakter (dengan tanda hubung)
Dapat diurutkan berdasarkan waktu pembuatanYaTidak
EncodingBase32 CrockfordHeksadesimal
Memuat stempel waktuYa (48 bit)Tidak
Aman untuk URL tanpa perlu escapeYaYa

Kedua format bertujuan menghasilkan pengidentifikasi yang unik di berbagai sistem tanpa otoritas pusat yang membagikan nomor. Perbedaan praktis utamanya adalah pengurutan: karena ULID diawali stempel waktu, pengurutan ULID sebagai teks biasa juga mengurutkannya berdasarkan waktu. UUID acak tidak memiliki sifat ini karena setiap bagiannya bersifat acak.

Kegunaan Umum

  • Kunci utama basis data: ULID memungkinkan basis data mengindeks baris baru kira-kira dalam urutan penyisipannya, yang ditangani banyak mesin basis data dengan lebih efisien daripada kunci yang sepenuhnya acak.
  • Sistem terdistribusi: server yang terpisah dapat menghasilkan ULID secara independen tanpa berkoordinasi dengan penghitung pusat, dan hasilnya masih hampir pasti unik.
  • Log peristiwa: karena ULID terurut berdasarkan waktu, daftar ID peristiwa dapat berfungsi sebagai linimasa kasar.
  • Pengidentifikasi API dan berkas: format tetap sepanjang 26 karakter yang aman untuk URL bekerja dengan baik dalam alamat web dan nama berkas.

Format pengidentifikasi terkait mencakup KSUID, yang juga mengenkode stempel waktu untuk pengurutan, serta ID Snowflake, yang digunakan oleh Twitter dan lainnya dan menggabungkan stempel waktu, pengidentifikasi mesin, serta penghitung.

Contoh Kode

Setiap contoh di bawah membentuk ULID dengan cara yang sama seperti dijelaskan dalam spesifikasi ULID: enkode stempel waktu 48 bit menjadi 10 karakter Base32 Crockford, enkode 80 bit keacakan menjadi 16 karakter tambahan, lalu gabungkan keduanya.

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

Pertanyaan yang sering diajukan

Untuk apa ULID digunakan? ULID digunakan sebagai pengidentifikasi unik untuk baris basis data, sumber daya API, atau peristiwa yang dicatat, ketika pengurutan berdasarkan waktu pembuatan juga bermanfaat.

Berapa panjang ULID? ULID selalu memiliki panjang 26 karakter: 10 karakter untuk stempel waktu dan 16 karakter untuk bagian acak.

Pengenkodean apa yang digunakan ULID? ULID menggunakan alfabet Base32 Crockford, yang terdiri dari digit 0–9 dan huruf A-Z dengan I, L, O, serta U dihapus untuk menghindari kerancuan dengan karakter lain.

Apa perbedaan ULID dari UUID? ULID terurut berdasarkan waktu pembuatan dan memiliki panjang 26 karakter. UUID acak (versi 4) tidak terurut berdasarkan waktu dan memiliki panjang 36 karakter termasuk tanda hubung.

Seberapa besar kemungkinan terjadi benturan antara dua ULID? 80 bit keacakan membuat benturan sangat kecil kemungkinannya. Diperlukan pembuatan sekitar 1,3 triliun ULID dalam milidetik yang sama untuk mencapai peluang 50% bahwa dua ULID mana pun akan sama.

Bisakah ULID dibuat tanpa koneksi internet? Ya. ULID hanya memerlukan jam lokal dan generator bilangan acak, sehingga dapat dibuat sepenuhnya secara luring.

Referensi

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