Pular para o conteúdo

Gerador de ULID - Crie IDs Únicos e Ordenáveis Online Gratuitamente

Ferramenta gratuita de geração de ULID cria identificadores únicos e ordenáveis instantaneamente. Gere ULIDs criptograficamente seguros para bancos de dados, APIs e sistemas distribuídos online.

Gerador de ULID

Insira um valor para ver os resultados
Calculadora de carregamento...
📚

Documentação

O que é um ULID?

Um ULID (Identificador Universalmente Único e Ordenável Lexicograficamente) é um código de 26 caracteres usado para identificar registros em um banco de dados ou um evento em um sistema distribuído. Ele combina o horário atual com dados aleatórios, de modo que uma lista de ULIDs ordenada alfabeticamente também fique ordenada pelo horário em que cada identificador foi criado. Um gerador de ULIDs é uma ferramenta que produz esses códigos.

Estrutura de um ULID

Um ULID tem duas partes, escritas uma depois da outra, sem separador:

  • Timestamp (10 caracteres): o número de milissegundos desde 1º de janeiro de 1970 (a época Unix), com até 48 bits.
  • Aleatoriedade (16 caracteres): 80 bits de dados aleatórios, adicionados para que dois ULIDs criados no mesmo milissegundo ainda sejam quase certamente diferentes.

As duas partes são escritas usando o alfabeto Base32 de Crockford: os dígitos de 0 a 9 e as letras de A a Z, exceto I, L, O e U. Essas quatro letras são omitidas porque podem ser confundidas com os dígitos 0 e 1 ou entre si. O resultado é uma string curta, fácil de ler em voz alta e segura para ser colocada diretamente em uma URL.

Como calcular um ULID

Um gerador de ULIDs cria um identificador em três etapas.

  1. Ler o horário atual em milissegundos desde a época Unix. Esse é um número de 48 bits.
  2. Gerar 80 bits de dados aleatórios, normalmente usando um gerador de números aleatórios criptograficamente seguro, o que produz 10 bytes aleatórios.
  3. Codificar as duas partes separadamente usando o alfabeto Base32 de Crockford: o timestamp de 48 bits se torna 10 caracteres, e o valor aleatório de 80 bits se torna 16 caracteres. As duas strings codificadas são unidas para formar o ULID final de 26 caracteres.

A codificação funciona lendo o número em grupos de 5 bits, porque cada caractere Base32 representa um de 32 valores possíveis (2^5 = 32). Dez caracteres comportam até 50 bits, espaço suficiente para o timestamp de 48 bits. Dezesseis caracteres comportam exatamente 80 bits, o que corresponde à parte aleatória sem deixar bits restantes.

Exemplo resolvido

Suponha que um gerador de ULIDs seja executado no timestamp 1712345678901 (milissegundos desde a época) e obtenha os bytes aleatórios [12, 240, 88, 3, 199, 45, 6, 231, 128, 17].

Etapa 1 – codificar o timestamp. Divida 1712345678901 repetidamente por 32, obtendo o resto a cada divisão e lendo os dígitos do último para o primeiro (essa é a conversão padrão de base). Isso produz a string de 10 caracteres 01HTQW311N.

Etapa 2 – codificar a aleatoriedade. Empacote os 10 bytes aleatórios em um fluxo de 80 bits e depois leia 5 bits por vez, convertendo cada grupo de 5 bits em um caractere Base32. Isso produz a string de 16 caracteres 1KR5G0Y75M3EF00H.

Etapa 3 – unir as partes. O ULID final é:

101HTQW311N 1KR5G0Y75M3EF00H
2

escrito sem o espaço: 01HTQW311N1KR5G0Y75M3EF00H, com 26 caracteres ao todo.

Como usar este gerador

O gerador é executado no navegador. Cada ULID é formado usando o relógio do navegador e 80 bits aleatórios novos obtidos do gerador de números aleatórios criptográficos do navegador. Assim, nenhum identificador é enviado a um servidor ou obtido dele.

  • Número de ULIDs aceita um número inteiro de 1 a 50. O padrão é 1.
  • Gerar ULID produz um novo lote. Alterar a quantidade também produz um novo lote.
  • Copiar, em um resultado, copia apenas aquele ULID. Quando mais de um é exibido, Copiar todos copia a lista inteira, com um ULID por linha.
  • Redefinir retorna a quantidade para 1 e gera um novo ULID.

Abaixo dos resultados, o painel Estrutura do ULID divide o primeiro ULID do lote em suas duas partes: os primeiros 10 caracteres (o timestamp) e os últimos 16 (a aleatoriedade).

ULID versus UUID

CaracterísticaULIDUUID (versão 4)
Comprimento26 caracteres36 caracteres (com hifens)
Ordenável pelo horário de criaçãoSimNão
CodificaçãoBase32 de CrockfordHexadecimal
Contém um timestampSim (48 bits)Não
Seguro para URL sem escapeSimSim

Os dois formatos buscam produzir identificadores únicos entre sistemas sem que uma autoridade central distribua números. A principal diferença prática está na ordenação: como um ULID começa com um timestamp, ordenar ULIDs como texto simples também os ordena pelo horário. Um UUID aleatório não tem essa propriedade, pois todas as suas partes são aleatórias.

Usos comuns

  • Chaves primárias de bancos de dados: os ULIDs permitem que um banco de dados indexe novas linhas aproximadamente na ordem em que foram inseridas, algo que muitos mecanismos de banco de dados tratam com mais eficiência do que chaves totalmente aleatórias.
  • Sistemas distribuídos: servidores separados podem gerar ULIDs de forma independente, sem coordenar a operação com um contador central, e os resultados ainda serão quase certamente únicos.
  • Registros de eventos: como os ULIDs são ordenados pelo horário, uma lista de IDs de eventos também pode funcionar como uma linha do tempo aproximada.
  • Identificadores de APIs e arquivos: o formato fixo de 26 caracteres, seguro para URLs, funciona bem em endereços da web e nomes de arquivos.

Entre os formatos de identificadores relacionados estão o KSUID, que também codifica um timestamp para permitir a ordenação, e os IDs Snowflake, usados pelo Twitter e por outras empresas, que combinam um timestamp, um identificador de máquina e um contador.

Exemplos de código

Cada exemplo abaixo cria um ULID da mesma forma descrita na especificação de ULID: codifica o timestamp de 48 bits como 10 caracteres Base32 de Crockford, codifica 80 bits de aleatoriedade como mais 16 caracteres e une as duas partes.

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

Perguntas frequentes

Para que serve um ULID?
Um ULID é usado como identificador único de uma linha de banco de dados, de um recurso de API ou de um evento registrado, quando também é útil ordenar os itens pelo horário de criação.

Qual é o tamanho de um ULID?
Um ULID sempre tem 26 caracteres: 10 caracteres para o timestamp e 16 para a parte aleatória.

Que codificação um ULID usa?
Um ULID usa o alfabeto Base32 de Crockford, formado pelos dígitos de 0 a 9 e pelas letras de A a Z, com I, L, O e U removidas para evitar confusão com outros caracteres.

Qual é a diferença entre um ULID e um UUID?
Um ULID é ordenado pelo horário de criação e tem 26 caracteres. Um UUID aleatório (versão 4) não é ordenado pelo horário e tem 36 caracteres, incluindo os hifens.

Qual é a probabilidade de colisão entre dois ULIDs?
Os 80 bits de aleatoriedade tornam as colisões extremamente improváveis. Seria necessário gerar aproximadamente 1,3 trilhão de ULIDs dentro do mesmo milissegundo para chegar a uma probabilidade de 50% de que dois deles coincidam.

É possível gerar ULIDs sem conexão com a internet?
Sim. Um ULID precisa apenas do relógio local e de um gerador de números aleatórios, portanto pode ser criado totalmente offline.

Referências

  1. "Especificação de ULID." GitHub, https://github.com/ulid/spec.
  2. "Codificação Base32 de Crockford." http://www.crockford.com/base32.html.