Gerador de UUID
v4 são 122 bits aleatórios — imprevisível, e a escolha certa quando o ID não deve revelar nada. A ordem aleatória o torna uma chave primária ruim.
Nada do que você digita aqui é armazenado, registrado ou compartilhado.
Gere UUIDs no seu navegador, aleatórios v4 ou ordenáveis por tempo v7. Escolha quantos precisa e copie um por um ou todos de uma vez.
Como usar
- Escolha v4 para IDs aleatórios ou v7 para IDs ordenáveis por tempo.
- Escolha quantos gerar.
- Copie um valor individual, ou use Copiar tudo.
O que os 128 bits guardam
Um UUID tem dezesseis bytes, escritos como 32 dígitos hexadecimais no conhecido agrupamento 8-4-4-4-12. Nem todos são livres: quatro bits identificam a versão e mais dois ou três identificam a variante, e é por isso que o décimo terceiro dígito de todo UUID gerado aqui é 4 ou 7, e o décimo sétimo é sempre 8, 9, a ou b.
Sobram 122 bits para um UUID versão 4 preencher aleatoriamente. A versão 7 usa os primeiros 48 bits para um timestamp em milissegundos e preenche os 74 restantes com aleatoriedade, trocando um pouco de imprevisibilidade por ordem.
Os hifens não carregam informação, e maiúsculas e minúsculas também não, embora a RFC 9562 diga para gerar em minúsculas e aceitar as duas na entrada. O prefixo urn:uuid: e as chaves que as ferramentas do Windows gostam de usar são apresentação, não conteúdo.
Por que o v7 existe
UUIDs versão 4 são uniformemente aleatórios, o que é exatamente o que você quer num identificador que não deve revelar nada, e exatamente o que você não quer numa chave primária.
Um índice B-tree mantém as entradas ordenadas. Insira uma chave aleatória e ela cai em qualquer ponto dessa ordem, então cada inserção toca uma página diferente, e quando o conjunto de páginas em uso passa do tamanho da memória, cada inserção vira também uma leitura, além da escrita. As páginas enchem de forma irregular e se dividem, o índice fica maior que os dados que indexa, e a vazão de escrita cai conforme a tabela cresce. Com chaves sequenciais, as inserções vão para o final, uma única página fica quente e nada disso acontece.
A versão 7 coloca um timestamp nos bits mais altos para que IDs gerados depois fiquem ordenados após os gerados antes, recuperando essa localidade sem perder a unicidade global e sem precisar de coordenação entre máquinas. Foi por isso que a RFC 9562 a incluiu, e hoje ela é o padrão certo para uma coluna de chave.
A troca é real: um UUID v7 revela aproximadamente quando a linha foi criada, e IDs consecutivos revelam ordem e um ritmo aproximado. Quando o identificador é exposto publicamente e qualquer uma dessas informações é sensível, o v4 continua sendo a escolha certa.
Colisões
Dois UUIDs versão 4 colidem quando 122 bits aleatórios se repetem. O jeito comum de tornar esse número compreensível é o limite do aniversário: seria preciso gerar cerca de um bilhão de UUIDs por segundo durante uns 85 anos para que a chance de uma única colisão em todo o conjunto chegasse a 50%.
Então, na prática, não. As falhas realistas não são estatísticas. São um gerador mal inicializado - máquinas virtuais clonadas do mesmo snapshot, dispositivos embarcados sem entropia na inicialização -, código que corta um UUID para caber numa coluna e destrói a maior parte da aleatoriedade, ou uma biblioteca que recorre silenciosamente a uma fonte não criptográfica. Os bits aqui vêm do gerador criptográfico do navegador, e o hábito útil em outros lugares é verificar o que a sua biblioteca realmente usa, em vez de supor.
Como armazenar
A forma de texto tem 36 caracteres. O valor tem 16 bytes. Guardar UUIDs como char(36) mais que dobra o espaço e, em bancos onde todo índice secundário carrega uma cópia da chave primária, multiplica esse custo pelo schema inteiro.
O PostgreSQL tem um tipo uuid nativo que armazena 16 bytes e aceita a forma de texto na entrada. O MySQL não tem esse tipo; o convencional é usar binary(16) com conversão na fronteira, e para UUIDs versão 1 existe o conhecido truque de reordenar os bytes de tempo para recuperar a ordenação, algo que a versão 7 torna desnecessário.
Se você exibe UUIDs numa URL e o tamanho incomoda, codifique os mesmos 16 bytes em base32 ou base64url em vez de encurtar o valor. Truncar parece funcionar até o momento em que deixa de funcionar.
O conjunto completo de versões
A versão 1 codifica um timestamp de 60 bits e o endereço MAC da máquina, o que a torna ordenável e rastreável - a segunda propriedade é o motivo de ela ter caído em desuso, já que revela qual máquina gerou um identificador. A versão 2 é uma variante de segurança do DCE que quase ninguém usa. As versões 3 e 5 são determinísticas: elas aplicam hash a um namespace e a um nome, com MD5 e SHA-1 respectivamente, de modo que a mesma entrada sempre produz o mesmo identificador.
A versão 4 é pura aleatoriedade e virou o padrão em todo lugar porque não exige coordenação, nem relógio, nem identidade de máquina. A versão 6 é a versão 1 reorganizada para que o timestamp ordene corretamente, e a versão 7 é a resposta moderna: um timestamp em milissegundos nos bits mais altos seguido de aleatoriedade, padronizada na RFC 9562 em 2024.
A versão 5 merece ser usada mais do que é. Quando você precisa de um identificador estável derivado de algo que já tem - uma URL, um caminho de arquivo, o nome de um tenant -, transformá-lo em um UUID por hash dá a todos os sistemas o mesmo identificador, sem tabela de consulta e sem nenhuma etapa de coordenação.
As alternativas e quando elas se encaixam melhor
O ULID codifica um timestamp e aleatoriedade em 26 caracteres de base32 de Crockford: ordenável, sem diferenciar maiúsculas de minúsculas e mais curto que um UUID em forma de texto. Ele é anterior à versão 7 e resolve o mesmo problema, então sistemas novos geralmente podem simplesmente usar v7 e permanecer dentro do padrão.
Os identificadores Snowflake, originalmente do Twitter, empacotam um timestamp, um id de máquina e um número de sequência em 64 bits. São compactos, ordenáveis e exigem pouca coordenação, ao custo de cada nó precisar de um id distinto. Eles também ultrapassam o que um number de JavaScript representa com exatidão, e é por isso que as APIs que os usam retornam strings.
O nanoid produz strings aleatórias curtas para URLs, com um alfabeto configurável - os 21 caracteres padrão carregam aproximadamente a mesma entropia de um UUID v4 na metade do texto. E um simples inteiro autoincrementado ainda é a melhor escolha em muitos sistemas: o menor, o mais rápido de indexar e perfeitamente adequado quando os identificadores permanecem internos.
O que um identificador revela quando é público
Inteiros sequenciais em URLs públicas contam a todos o seu volume e permitem que qualquer um percorra a faixa: /orders/1001 sugere que /orders/1000 existe. Combinado com uma verificação de autorização ausente, isso é a classe de vulnerabilidade conhecida como referência direta insegura a objeto, que continua sendo uma das falhas mais encontradas em aplicações web.
Um UUID v4 aleatório elimina a enumeração, e só isso. Ele não é controle de acesso: um identificador que ninguém consegue adivinhar continua sendo um identificador que qualquer um que o obtenha pode usar, e URLs vazam por cabeçalhos referrer, histórico do navegador, logs, capturas de tela e links compartilhados. Toda requisição ainda precisa verificar se aquele usuário pode ver aquele recurso.
A versão 7 devolve um pouco dessa opacidade. Ela revela aproximadamente quando um registro foi criado, e identificadores consecutivos expõem a ordem e o ritmo - o suficiente para inferir quantos clientes se cadastraram em uma semana. Quando qualquer uma dessas coisas for sensível em um identificador público, use v7 internamente como chave primária e exponha um v4 ou um slug separado.
Chaves primárias, índices e armazenamento
Um índice B-tree mantém as entradas ordenadas, então chaves aleatórias espalham as inserções por todo o índice. Quando o índice deixa de caber na memória, cada inserção passa a ser também uma leitura, as páginas se enchem de forma desigual e se dividem, e a vazão de escrita cai conforme a tabela cresce. Chaves sequenciais são anexadas ao final, mantêm uma única página quente e evitam tudo isso - o que é todo o argumento a favor da versão 7.
O armazenamento também importa. Um UUID tem 16 bytes; sua forma em texto tem 36 caracteres. O PostgreSQL tem um tipo uuid nativo que guarda a forma binária e aceita texto na entrada. O MySQL não tem esse tipo, então a convenção é BINARY(16) com conversão na fronteira da aplicação. Armazenar como texto mais que dobra o espaço, e em motores em que cada índice secundário carrega uma cópia da chave primária, esse custo se multiplica por todo o esquema.
O meio-termo mais comum é uma chave primária inteira e pequena para os joins internos e um UUID como identificador externo com um índice único. Isso mantém o layout físico enxuto e ao mesmo tempo dá ao mundo externo uma referência opaca.
Gerando identificadores com segurança no código
Use a função da plataforma em vez de montar um na mão: crypto.randomUUID em navegadores e no Node, uuid4 em Python, UUID.randomUUID em Java. Elas puxam do gerador criptográfico, que é o que faz o argumento sobre colisões se sustentar. Uma biblioteca que recorre a Math.random - alguns pacotes JavaScript mais antigos faziam isso - produz identificadores que parecem idênticos e são previsíveis.
Os modos de falha realistas não são estatísticos. Máquinas virtuais clonadas do mesmo snapshot podem iniciar com o mesmo pool de entropia; dispositivos embarcados podem ter quase nenhuma entropia na inicialização; e um código que trunca um UUID para caber em uma coluna destrói a maior parte da aleatoriedade e deixa algo que ainda parece um identificador.
Dois hábitos evitam o resto. Compare identificadores sem diferenciar maiúsculas de minúsculas, já que a RFC 9562 diz para emitir em minúsculas mas aceitar qualquer forma, e remova as chaves e o prefixo urn:uuid: que as ferramentas do Windows acrescentam. E valide na entrada em vez de confiar no formato, porque uma string com cara de UUID em uma URL continua sendo entrada do usuário.
Perguntas frequentes
- Qual a diferença entre UUID v4 e v7?
- O v4 tem 122 bits aleatórios, então não revela nada e é imprevisível. O v7 começa com um timestamp de 48 bits em milissegundos seguido de bits aleatórios, então IDs gerados depois sempre ordenam após os anteriores. O v4 esconde o horário de criação; o v7 o expõe, mas ordena.
- Qual devo usar como chave primária de banco de dados?
- O v7. Chaves v4 aleatórias espalham as inserções por todo o índice, o que fragmenta as páginas da árvore B e prejudica a taxa de escrita e a localidade de cache. Chaves v7 são acrescentadas em ordem, comportando-se muito mais como um inteiro auto-incrementável, sem perder a unicidade global.
- Estes UUIDs são criptograficamente aleatórios?
- Sim. Os bits aleatórios vêm de crypto.getRandomValues, o gerador de números aleatórios criptograficamente seguro do navegador, não de Math.random. Um UUID v4 tem 122 bits aleatórios, então colisões não são uma preocupação prática.
- Por que não há opção v1 ou v5?
- O v1 codifica um endereço MAC e o estado do relógio, o que vaza a identidade do host, e a RFC 9562 aponta sistemas novos para o v7. O v3 e o v5 são baseados em nome: eles fazem hash de um namespace mais um nome para produzir um ID determinístico, o que exige entradas próprias e pertence a outra ferramenta.
- Os UUIDs são gerados em um servidor?
- Não. Eles são gerados no seu navegador e nunca transmitidos, então ninguém mais, incluindo este site, chega a vê-los.
- Qual a diferença entre UUID e GUID?
- Nenhuma, na prática. GUID é o nome que a Microsoft dá ao mesmo identificador de 128 bits, e é por isso que as ferramentas do Windows costumam mostrá-lo entre chaves. Use a opção de chaves se precisar dessa forma.
Última atualização:
Inclua os passos, o resultado esperado e o resultado real. Remova segredos e dados pessoais.
