1001Ferramentas
🔍Validadores

Detector de Versão de UUID

Detecta a versão de um UUID (v1, v2, v3, v4, v5, v6, v7, v8) baseado no campo de versão e variante. Mostra também o timestamp embutido em UUIDv1/v6/v7.

Identificando a versão do UUID: o único dígito hex que diz tudo

Quando você recebe um UUID por aí — em um corpo JSON, uma linha de banco, um path de URL — a primeira coisa que normalmente precisa saber é qual versão o gerou. A versão não é um campo separado; é codificada dentro do próprio UUID, em um único dígito hex em posição fixa. Quando você consegue ler esse dígito, sabe se dá para extrair um timestamp dele, se ele vaza um endereço MAC, se é ordenável e se seu código de parsing vai travar em um layout que ele não espera.

Este validador é mais estreito do que um verificador genérico de UUID (validador-uuid): em vez de só dizer "válido ou não", ele diz qual das oito versões a entrada pertence, para que o dispatch da lógica downstream fique trivial.

Anatomia do UUID: onde mora a versão

Um UUID canônico tem 36 caracteres no padrão 8-4-4-4-12: xxxxxxxx-xxxx-Vxxx-vxxx-xxxxxxxxxxxx. Os dois caracteres que carregam significado são a posição 14 (o primeiro caractere após o segundo hífen — o V acima) e a posição 19 (o primeiro após o terceiro hífen — o v acima):

  • Posição 14 — nibble de versão: um dígito hex de 1 a 8, dizendo qual layout RFC foi usado.
  • Posição 19 — nibble de variante: precisa ser 8, 9, A ou B para a variante RFC 4122 / 9562 — os bits altos em binário são 10x. Cerca de 96,875% dos UUIDs gerados caem nessa variante; os 3,125% restantes são reservados para NCS legado, GUID Microsoft e uso futuro.

Lida em JavaScript, a versão é uma linha:

function uuidVersion(uuid) {
  // index 14 no string indexing base-0
  return parseInt(uuid.charAt(14), 16)
}

uuidVersion('f47ac10b-58cc-4372-a567-0e02b2c3d479') // 4
uuidVersion('017f22e2-79b0-7cc3-98c4-dc0c0c07398f') // 7

O que cada dígito de versão significa

  • 1xxxxxxxv1 — timestamp de 60 bits (ticks de 100 ns desde 1582-10-15) + 14 bits de clock sequence + 48 bits de endereço MAC. Ordenável mas vaza o MAC do host.
  • 2xxxxxxxv2 — DCE Security version. Reservada; quase nunca aparece em sistemas modernos.
  • 3xxxxxxxv3 — hash MD5 de um UUID de namespace e um nome. Determinístico.
  • 4xxxxxxxv4 — 122 bits de aleatoriedade pura. Versão mais comum historicamente; não ordenável.
  • 5xxxxxxxv5 — igual a v3 mas SHA-1. Preferida sobre v3 por segurança.
  • 6xxxxxxxv6 — v1 com os campos de timestamp reordenados para que o UUID ordene lexicograficamente no tempo.
  • 7xxxxxxxv7 — timestamp Unix em milissegundos de 48 bits + 74 bits aleatórios. Recomendação da RFC 9562 de 2024 para novos sistemas.
  • 8xxxxxxxv8 — layout totalmente custom para aplicações que precisam de codificação própria mantendo conformidade com a RFC.

Valores especiais: Nil UUID e Max UUID

Duas strings ficam fora do esquema de versão:

  • Nil UUID00000000-0000-0000-0000-000000000000. Definido pela RFC 4122 como "sem valor", usado como sentinela significando NULL. Não tem dígito de versão (posição 14 é 0, fora da faixa).
  • Max UUIDffffffff-ffff-ffff-ffff-ffffffffffff. Adicionado pela RFC 9562 (2024) para o mesmo papel no outro extremo do espaço de valores. Posição 14 é f, também fora da faixa 1-8.

Um detector de versão deve devolver um marcador especial para esses casos — não travar, não mentir dizendo que são v4 válidos. As duas versões do pacote npm uuid expõem as constantes NIL e MAX e os helpers validate(uuid) / version(uuid) que tratam isso.

Por que detectar versão importa: dispatch da lógica de parsing

Versões diferentes de UUID carregam payloads diferentes, então o dispatch por versão é essencial quando você quer extrair metadados:

function timestampDoUuid(uuid) {
  switch (uuidVersion(uuid)) {
    case 1: return v1Timestamp(uuid)  // 100 ns desde 1582
    case 6: return v6Timestamp(uuid)  // mesmo epoch, reordenado
    case 7: return v7Timestamp(uuid)  // Unix ms — fácil
    default: return null              // v3/v4/v5/v8 não têm timestamp
  }
}

O anti-padrão clássico é assumir que todo UUID é v4 e jogá-lo num parser que só sabe randômico — código que funcionou por anos trava de repente no dia em que alguém ativa v7 na aplicação ou uma integração de terceiros começa a mandar v1. Ramifique sempre pelo dígito de versão explicitamente, ou use uma biblioteca que faça isso por você.

Contexto brasileiro: migração para v7 em indexação de banco

Times de engenharia no Brasil que começaram em Rails ou Django com UUID v4 estão migrando para v7 especificamente por causa de fragmentação do índice B-tree. Inserts v4 randômicos se espalham pela árvore do índice e forçam splits constantes de página; inserts v7 chegam em ordem temporal e caem no fim da folha mais à direita, igualzinho a um auto-incremento. A virada é uma troca de uma linha na lib geradora (crypto.randomUUID()uuidv7()) e é totalmente compatível com o passado — os novos validam como UUIDs bem formados em qualquer lugar.

FAQ

Como exatamente identifico a versão? Lê o caractere no índice 14 da string de 36 caracteres (o primeiro caractere após o segundo hífen). Parseia como hex — esse inteiro de 1 a 8 é a versão. A posição 14 é 1-based para humanos, 0-based para programadores; a spec chama de nibble de "versão" dentro do terceiro grupo.

v4 ainda é a versão mais comum? Historicamente sim, porque crypto.randomUUID() em navegadores e a maioria dos helpers da stdlib default são v4. v7 está crescendo rápido desde a RFC 9562 em 2024 — novos apps Rails, extensões Postgres e ORMs estão virando o padrão.

v7 vai substituir v4? Gradualmente. Para tabelas novas, v7 é o melhor default (ordenável, indexa bem, sem vazamento de MAC). v4 mantém seu lugar quando você precisa de máxima imprevisibilidade para IDs públicos e não se importa com ordem de insert.

O que significa o Nil UUID? É o valor zero reservado, significando "ausente" — a spec recomenda tratá-lo como NULL. Não tem versão porque a posição 14 é 0, fora da faixa 1-8.

Por que a variante é 96,875%? A variante usa os dois bits altos da posição 19 (o nibble após o terceiro hífen). O padrão 10x significa bit alto = 1 e próximo = 0, deixando o terceiro bit livre — isso são 4 dos 16 hex possíveis (8, 9, A, B). O 96,875% vem de quanto do espaço da variante (não do espaço de dígito) pertence à RFC 4122/9562.

Ferramentas Relacionadas