Whiz Tools

ژنراتور ULID

ULID تولید شده:

ساختار ULID


زمان (10 کاراکتر)

تصادفی بودن (16 کاراکتر)

تولید ULID

مقدمه

ULID (شناسه یکتا و قابل مرتب‌سازی به‌صورت لغت‌نامه‌ای جهانی) یک شناسه یکتا است که زمان را با داده‌های تصادفی ترکیب می‌کند تا یک رشته ۲۶ کاراکتری ایجاد کند. ULIDها به‌گونه‌ای طراحی شده‌اند که قابل مرتب‌سازی به‌صورت لغت‌نامه‌ای باشند و در عین حال درجه بالایی از یکتایی و تصادفی بودن را حفظ کنند.

ساختار یک ULID

یک ULID از دو بخش اصلی تشکیل شده است:

  1. زمان (۱۰ کاراکتر): ۱۰ کاراکتر اول نمایانگر زمان به میلی‌ثانیه از زمان Unix Epoch (۱۹۷۰-۰۱-۰۱) است.
  2. تصادفی بودن (۱۶ کاراکتر): ۱۶ کاراکتر باقی‌مانده با استفاده از داده‌های تصادفی امن رمزنگاری شده تولید می‌شوند.

رشته ۲۶ کاراکتری نتیجه با استفاده از الفبای base32 کراکفورد (۰-۹ و A-Z، به‌جز I، L، O و U) رمزگذاری می‌شود.

فرمول

ULID با استفاده از مراحل زیر تولید می‌شود:

  1. تولید یک زمان ۴۸ بیتی (میلی‌ثانیه از زمان Unix Epoch).
  2. تولید ۸۰ بیت داده تصادفی امن رمزنگاری شده.
  3. رمزگذاری ۱۲۸ بیت ترکیبی با استفاده از رمزگذاری base32 کراکفورد.

محاسبه

تولیدکننده ULID مراحل زیر را انجام می‌دهد:

  1. دریافت زمان فعلی به میلی‌ثانیه.
  2. تولید ۱۰ بایت تصادفی (۸۰ بیت) با استفاده از یک تولیدکننده عدد تصادفی امن رمزنگاری شده.
  3. ترکیب زمان و داده‌های تصادفی به یک عدد ۱۲۸ بیتی.
  4. رمزگذاری عدد ۱۲۸ بیتی با استفاده از رمزگذاری base32 کراکفورد.

موارد استفاده

ULIDها در سناریوهای مختلف مفید هستند، از جمله:

  1. کلیدهای پایگاه داده: ULIDها می‌توانند به‌عنوان شناسه‌های یکتا برای رکوردهای پایگاه داده استفاده شوند و یکتایی و قابلیت مرتب‌سازی را تضمین کنند.
  2. سیستم‌های توزیع‌شده: در محیط‌های توزیع‌شده، ULIDها می‌توانند بدون هماهنگی بین گره‌ها تولید شوند.
  3. ثبت و ردیابی: ULIDها می‌توانند برای برچسب‌گذاری ورودی‌های لاگ یا ردیابی رویدادها استفاده شوند و شناسه‌ای یکتا و قابل مرتب‌سازی ارائه دهند.
  4. شناسه‌های مناسب برای URL: ULIDها ایمن برای URL هستند و می‌توانند به‌عنوان شناسه در URLها در برنامه‌های وب استفاده شوند.

جایگزین‌ها

در حالی که ULIDها چندمنظوره هستند، سیستم‌های شناسه یکتای دیگری نیز وجود دارند که باید در نظر گرفته شوند:

  1. UUID (شناسه یکتا جهانی): یک شناسه ۱۲۸ بیتی که شامل یک مؤلفه زمان نمی‌شود.
  2. KSUID (شناسه یکتا قابل مرتب‌سازی K): مشابه ULID اما با رمزگذاری زمان متفاوت.
  3. شناسه Snowflake: سیستم تولید شناسه یکتای توزیع‌شده توییتر که شامل یک زمان و شناسه کارگر است.

تاریخچه

ULIDها در سال ۲۰۱۶ توسط علیزین فیرستا به‌عنوان یک جایگزین برای UUIDها معرفی شدند. آن‌ها برای رفع برخی محدودیت‌های UUIDها طراحی شده‌اند، به‌ویژه از نظر قابلیت مرتب‌سازی و خوانایی. مشخصات ULID از زمان معرفی آن ثابت مانده است و پیاده‌سازی‌های مختلفی در زبان‌های برنامه‌نویسی مختلف موجود است.

مثال‌ها

در اینجا چند مثال کد برای تولید ULID در زبان‌های برنامه‌نویسی مختلف آورده شده است:

// پیاده‌سازی JavaScript
function generateULID() {
  const timestamp = Date.now().toString(36).padStart(10, '0');
  const randomness = crypto.getRandomValues(new Uint8Array(16))
    .reduce((acc, byte) => acc + byte.toString(36).padStart(2, '0'), '');
  return (timestamp + randomness).toUpperCase();
}

console.log(generateULID());
## پیاده‌سازی Python
import time
import secrets
import base64

def generate_ulid():
    timestamp = int(time.time() * 1000).to_bytes(6, byteorder="big")
    randomness = secrets.token_bytes(10)
    return base64.b32encode(timestamp + randomness).decode("ascii").lower()

print(generate_ulid())
// پیاده‌سازی Java
import java.security.SecureRandom;
import java.time.Instant;

public class ULIDGenerator {
    private static final SecureRandom random = new SecureRandom();
    private static final char[] ENCODING_CHARS = "0123456789ABCDEFGHJKMNPQRSTVWXYZ".toCharArray();

    public static String generateULID() {
        long timestamp = Instant.now().toEpochMilli();
        byte[] randomness = new byte[10];
        random.nextBytes(randomness);

        StringBuilder result = new StringBuilder();
        // رمزگذاری زمان
        for (int i = 9; i >= 0; i--) {
            result.append(ENCODING_CHARS[(int) (timestamp % 32)]);
            timestamp /= 32;
        }
        // رمزگذاری تصادفی بودن
        for (byte b : randomness) {
            result.append(ENCODING_CHARS[b & 31]);
        }
        return result.toString();
    }

    public static void main(String[] args) {
        System.out.println(generateULID());
    }
}

این مثال‌ها نحوه تولید ULIDها را در JavaScript، Python و Java نشان می‌دهند. شما می‌توانید این توابع را به نیازهای خاص خود تطبیق دهید یا آن‌ها را در سیستم‌های بزرگ‌تر که به شناسه‌های یکتا نیاز دارند، ادغام کنید.

منابع

  1. "مشخصات ULID." GitHub، https://github.com/ulid/spec. دسترسی در ۲ اوت ۲۰۲۴.
  2. "رمزگذاری Base32 کراکفورد." رمزگذاری Base32، http://www.crockford.com/base32.html. دسترسی در ۲ اوت ۲۰۲۴.
  3. "UUID در مقابل ULID." Stack Overflow، https://stackoverflow.com/questions/54222235/uuid-vs-ulid. دسترسی در ۲ اوت ۲۰۲۴.
بازخورد