Whiz Tools

ULID Generator

Generated ULID:

ULID Structure


Timestamp (10 chars)

Randomness (16 chars)

ULID Generator

Introduction

A ULID (Universally Unique Lexicographically Sortable Identifier) is a unique identifier that combines a timestamp with random data to create a 26-character string. ULIDs are designed to be lexicographically sortable while maintaining a high degree of uniqueness and randomness.

Structure of a ULID

A ULID consists of two main parts:

  1. Timestamp (10 characters): The first 10 characters represent the time in milliseconds since the Unix Epoch (1970-01-01).
  2. Randomness (16 characters): The remaining 16 characters are generated using cryptographically secure random data.

The resulting 26-character string is encoded using Crockford's base32 alphabet (0-9 and A-Z, excluding I, L, O, and U).

Formula

The ULID is generated using the following steps:

  1. Generate a 48-bit timestamp (milliseconds since Unix Epoch).
  2. Generate 80 bits of cryptographically secure random data.
  3. Encode the combined 128 bits using Crockford's base32 encoding.

Calculation

The ULID generator performs the following steps:

  1. Get the current timestamp in milliseconds.
  2. Generate 10 random bytes (80 bits) using a cryptographically secure random number generator.
  3. Combine the timestamp and random data into a 128-bit integer.
  4. Encode the 128-bit integer using Crockford's base32 encoding.

Use Cases

ULIDs are useful in various scenarios, including:

  1. Database keys: ULIDs can be used as unique identifiers for database records, ensuring uniqueness and sortability.
  2. Distributed systems: In distributed environments, ULIDs can be generated without coordination between nodes.
  3. Logging and tracing: ULIDs can be used to tag log entries or trace events, providing a sortable and unique identifier.
  4. URL-friendly IDs: ULIDs are URL-safe and can be used in web applications as identifiers in URLs.

Alternatives

While ULIDs are versatile, there are other unique identifier systems to consider:

  1. UUID (Universally Unique Identifier): A 128-bit identifier that doesn't include a timestamp component.
  2. KSUID (K-Sortable Unique IDentifier): Similar to ULID but with a different timestamp encoding.
  3. Snowflake ID: Twitter's distributed unique ID generation system, which includes a timestamp and worker ID.

History

ULIDs were introduced in 2016 by Alizain Feerasta as an alternative to UUIDs. They were designed to address some limitations of UUIDs, particularly in terms of sortability and readability. The ULID specification has remained stable since its introduction, with various implementations available in different programming languages.

Examples

Here are some code examples to generate ULIDs in different programming languages:

// JavaScript implementation
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 implementation
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 implementation
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();
        // Encode timestamp
        for (int i = 9; i >= 0; i--) {
            result.append(ENCODING_CHARS[(int) (timestamp % 32)]);
            timestamp /= 32;
        }
        // Encode randomness
        for (byte b : randomness) {
            result.append(ENCODING_CHARS[b & 31]);
        }
        return result.toString();
    }

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

These examples demonstrate how to generate ULIDs in JavaScript, Python, and Java. You can adapt these functions to your specific needs or integrate them into larger systems requiring unique identifiers.

References

  1. "ULID Specification." GitHub, https://github.com/ulid/spec. Accessed 2 Aug. 2024.
  2. "Crockford's Base32 Encoding." Base32 Encoding, http://www.crockford.com/base32.html. Accessed 2 Aug. 2024.
  3. "UUID vs ULID." Stack Overflow, https://stackoverflow.com/questions/54222235/uuid-vs-ulid. Accessed 2 Aug. 2024.
Feedback