Qual versão do UUID você deve usar? Vi muitos tópicos explicando o que cada versão implica, mas estou tendo problemas para descobrir o que é melhor para quais aplicativos.
Existem duas maneiras diferentes de gerar um UUID.
Se você só precisa de um ID exclusivo, deseja uma versão 1 ou 4.
Versão 1: gera um ID exclusivo com base no endereço MAC da placa de rede e em um timer. Esses IDs são fáceis de prever (dado um, posso adivinhar outro) e podem ser rastreados até sua placa de rede. Não é recomendado criá-los.
Versão 4: são gerados a partir de números aleatórios (ou pseudo-aleatórios). Se você só precisa gerar um UUID, provavelmente é isso que você deseja.
Se você sempre gerar o mesmo UUID a partir de um determinado nome, deseje uma versão 3 ou 5.
Versão 3: gera um ID exclusivo a partir de um hash MD5 de um espaço para nome e nome. Se você precisar de compatibilidade com versões anteriores (com outro sistema que gera UUIDs a partir de nomes), use isso.
Versão 5: gera um ID exclusivo a partir de um hash SHA-1 de um espaço para nome e nome. Esta é a versão preferida.
Eu acrescentaria: Se você precisar gerar um reproducibleUUID a partir de um determinado nome, deseja uma versão 3 ou 5. Se você alimentar esse algoritmo com a mesma entrada, ele gerará a mesma saída.
anregen
3
Em um ambiente de computação em nuvem (como AWS ou GAE), parece que a fraqueza da Versão 1 é atenuada no esquecimento. Onde é provável que existam milhares de endereços MAC diferentes aplicados ao gerador UUID de uma determinada aplicação ao longo do tempo, eliminando a previsibilidade e / ou rastreabilidade.
Buffalo Rabor
3
@ user239558 Dado que o objetivo de um UUID é sua exclusividade, o UUIDv5 ainda pode ser preferido.
Epicurista
7
Esse comentário sobre a versão 1 ser "não recomendado" é excessivamente simplista. Em muitas situações, estas são realmente boas e preferíveis. Mas se você tiver preocupações de segurança sobre o vazamento de um desses itens de informação de um UUID que possa ser disponibilizado para atores não confiáveis: (a) o endereço MAC da máquina que está criando o UUID ou (b) a data e hora em que foi criado, evite a Versão 1. Se essas duas informações não forem sensíveis, a Versão 1 é um excelente caminho a percorrer.
Basil Bourque
9
O que aconteceu com a versão 2?
Matthew Woo
53
Se você deseja um número aleatório, use uma biblioteca de números aleatórios. Se você deseja um identificador exclusivo com efetivamente 0,00 ... muito mais 0s aqui ... 001% de chance de colisão, use o UUIDv1. Veja a publicação de Nick para UUIDv3 e v5.
UUIDv1 NÃO é seguro. Não é para ser assim. É para ser ÚNICO, não impossível de adivinhar. O UUIDv1 usa o registro de data e hora atual, além de um identificador de máquina, além de algumas informações aleatórias para criar um número que nunca será gerado por esse algoritmo novamente. Isso é apropriado para um ID de transação (mesmo se todo mundo estiver fazendo milhões de transações / s).
Para ser sincero, não entendo por que o UUIDv4 existe ... ao ler o RFC4122 , parece que essa versão NÃO elimina a possibilidade de colisões. É apenas um gerador de números aleatórios. Se isso for verdade, você tem uma boa chance de duas máquinas no mundo criarem o mesmo "UUID" v4 (aspas, porque não há um mecanismo para garantir a exclusividade da U.niversal). Nessa situação, não acho que o algoritmo pertença a uma RFC que descreve métodos para gerar valores únicos. Pertencia a uma RFC sobre gerar aleatoriedade. Para um conjunto de números aleatórios:
O algoritmo V4 não é serial, o que significa que há uma chance de os dois primeiros UUIDs gerados pela v4 corresponderem. Só porque existem muitas opções, não significa que você precise ficar sem opções exclusivas antes de gerar uma repetição. Isso pode acontecer a qualquer momento.
anregen
7
Você não está realmente fazendo as contas. Nós (como espécie) não estamos gerando 1 bilhão de UUIDs a cada segundo. Portanto, temos mais de 100 anos até a primeira colisão (em média).
Kevin
31
A V4 "pode" colidir, mas a probabilidade é excepcionalmente baixa de que, na maioria dos casos de uso, vale o risco. Re: "duas máquinas no mundo acabam criando o mesmo 'UUID'v4", bem, claro, mas isso não é um problema, porque a maioria das máquinas no mundo que usam os UUIDs as usam em contextos diferentes. Quero dizer, se eu gerar o mesmo UUID para meu próprio aplicativo interno e para o seu aplicativo interno, isso não importa. As colisões só importam se ocorrerem no mesmo contexto. (lembre-se, mesmo dentro de um aplicativo, muitos do UUID não tem que ser único em toda a aplicação, apenas o contexto em que são usados em)
6
Parece que, se você não precisa que seu Guid seja seguro, use a versão 1. Se você precisar dele seguro e tenha sorte (ou realmente não tenha azar), use a versão 4.
Vaccano
16
Essa é uma pergunta muito geral. Uma resposta é: "depende de que tipo de UUID você deseja gerar". Mas uma melhor é a seguinte: "Bem, antes de responder, você pode nos dizer por que precisa codificar seu próprio algoritmo de geração UUID em vez de chamar a funcionalidade de geração UUID que a maioria dos sistemas operacionais modernos oferece?"
Fazer isso é mais fácil e seguro e, como você provavelmente não precisa gerar o seu próprio, por que se preocupar em codificar uma implementação? Nesse caso, a resposta passa a ser o que quer que seu sistema operacional, linguagem de programação ou estrutura forneça. Por exemplo, no Windows, há CoCreateGuid ou UuidCreate ou um dos vários wrappers disponíveis nas diversas estruturas em uso. No Linux, há uuid_generate .
Se, por algum motivo, você absolutamente precisar gerar o seu próprio, pelo menos tenha o bom senso de evitar UUIDs v1 e v2. É complicado acertar as coisas. Em vez disso, atenha-se aos UUIDs v3, v4 ou v5.
Atualização : em um comentário, você menciona que está usando Python e cria um link para isso . Examinando a interface fornecida, a opção mais fácil para você seria gerar um UUID v4 (ou seja, um criado a partir de dados aleatórios) chamando uuid.uuid4().
Se você tiver alguns dados dos quais você precisa (ou pode) fazer o hash para gerar um UUID, poderá usar a v3 (que depende do MD5) ou a v5 (que depende do SHA1). Gerar um UUID v3 ou v5 é simples: primeiro escolha o tipo de UUID que você deseja gerar (você provavelmente deve escolher v5) e, em seguida, escolha o espaço para nome apropriado e chame a função com os dados que deseja usar para gerar o UUID. Por exemplo, se você estiver hash um URL, você usaria NAMESPACE_URL:
Uma boa propriedade dos URLs v3 e v5 é que eles devem ser interoperáveis entre implementações. Em outras palavras, se dois sistemas diferentes estiverem usando uma implementação que esteja em conformidade com a RFC4122, eles (ou pelo menos deveriam ) criarão o mesmo UUID se todas as outras coisas forem iguais (por exemplo, gerar a mesma versão UUID, com o mesmo espaço de nome e o mesmos dados). Essa propriedade pode ser muito útil em algumas situações (especialmente em cenários de armazenamento endereçável por conteúdo), mas talvez não no seu caso particular.
Eu acho que é porque o OP não perguntou: como "codifico [meu] próprio algoritmo de geração UUID em vez de chamar a funcionalidade de geração UUID que a maioria dos sistemas operacionais modernos fornece?"
anregen
Além disso, acho que é uma boa explicação para UUIDv3 e v5. Veja minha resposta abaixo sobre por que eu acho que a v1 pode ser uma boa escolha.
anregen
o que é NAMESPACE_URL? é uma variável que posso obter? de onde?
stackdave
@stackdave NAMESPACE_URLé um UUID geralmente igual a 6ba7b811-9dad-11d1-80b4-00c04fd430c8, seguindo a recomendação feita na página 30 da RFC-4122 .
Respostas:
Existem duas maneiras diferentes de gerar um UUID.
Se você só precisa de um ID exclusivo, deseja uma versão 1 ou 4.
Versão 1: gera um ID exclusivo com base no endereço MAC da placa de rede e em um timer. Esses IDs são fáceis de prever (dado um, posso adivinhar outro) e podem ser rastreados até sua placa de rede. Não é recomendado criá-los.
Versão 4: são gerados a partir de números aleatórios (ou pseudo-aleatórios). Se você só precisa gerar um UUID, provavelmente é isso que você deseja.
Se você sempre gerar o mesmo UUID a partir de um determinado nome, deseje uma versão 3 ou 5.
Versão 3: gera um ID exclusivo a partir de um hash MD5 de um espaço para nome e nome. Se você precisar de compatibilidade com versões anteriores (com outro sistema que gera UUIDs a partir de nomes), use isso.
Versão 5: gera um ID exclusivo a partir de um hash SHA-1 de um espaço para nome e nome. Esta é a versão preferida.
fonte
reproducible
UUID a partir de um determinado nome, deseja uma versão 3 ou 5. Se você alimentar esse algoritmo com a mesma entrada, ele gerará a mesma saída.Se você deseja um número aleatório, use uma biblioteca de números aleatórios. Se você deseja um identificador exclusivo com efetivamente 0,00 ... muito mais 0s aqui ... 001% de chance de colisão, use o UUIDv1. Veja a publicação de Nick para UUIDv3 e v5.
UUIDv1 NÃO é seguro. Não é para ser assim. É para ser ÚNICO, não impossível de adivinhar. O UUIDv1 usa o registro de data e hora atual, além de um identificador de máquina, além de algumas informações aleatórias para criar um número que nunca será gerado por esse algoritmo novamente. Isso é apropriado para um ID de transação (mesmo se todo mundo estiver fazendo milhões de transações / s).
Para ser sincero, não entendo por que o UUIDv4 existe ... ao ler o RFC4122 , parece que essa versão NÃO elimina a possibilidade de colisões. É apenas um gerador de números aleatórios. Se isso for verdade, você tem uma boa chance de duas máquinas no mundo criarem o mesmo "UUID" v4 (aspas, porque não há um mecanismo para garantir a exclusividade da U.niversal). Nessa situação, não acho que o algoritmo pertença a uma RFC que descreve métodos para gerar valores únicos. Pertencia a uma RFC sobre gerar aleatoriedade. Para um conjunto de números aleatórios:
fonte
set_size
é 2 ^ 122, que é muito grande .Essa é uma pergunta muito geral. Uma resposta é: "depende de que tipo de UUID você deseja gerar". Mas uma melhor é a seguinte: "Bem, antes de responder, você pode nos dizer por que precisa codificar seu próprio algoritmo de geração UUID em vez de chamar a funcionalidade de geração UUID que a maioria dos sistemas operacionais modernos oferece?"
Fazer isso é mais fácil e seguro e, como você provavelmente não precisa gerar o seu próprio, por que se preocupar em codificar uma implementação? Nesse caso, a resposta passa a ser o que quer que seu sistema operacional, linguagem de programação ou estrutura forneça. Por exemplo, no Windows, há CoCreateGuid ou UuidCreate ou um dos vários wrappers disponíveis nas diversas estruturas em uso. No Linux, há uuid_generate .
Se, por algum motivo, você absolutamente precisar gerar o seu próprio, pelo menos tenha o bom senso de evitar UUIDs v1 e v2. É complicado acertar as coisas. Em vez disso, atenha-se aos UUIDs v3, v4 ou v5.
Atualização : em um comentário, você menciona que está usando Python e cria um link para isso . Examinando a interface fornecida, a opção mais fácil para você seria gerar um UUID v4 (ou seja, um criado a partir de dados aleatórios) chamando
uuid.uuid4()
.Se você tiver alguns dados dos quais você precisa (ou pode) fazer o hash para gerar um UUID, poderá usar a v3 (que depende do MD5) ou a v5 (que depende do SHA1). Gerar um UUID v3 ou v5 é simples: primeiro escolha o tipo de UUID que você deseja gerar (você provavelmente deve escolher v5) e, em seguida, escolha o espaço para nome apropriado e chame a função com os dados que deseja usar para gerar o UUID. Por exemplo, se você estiver hash um URL, você usaria
NAMESPACE_URL
:uuid.uuid3(uuid.NAMESPACE_URL, 'https://ripple.com')
Observe que este UUID será diferente do UUID v5 para o mesmo URL, que é gerado assim:
uuid.uuid5(uuid.NAMESPACE_URL, 'https://ripple.com')
Uma boa propriedade dos URLs v3 e v5 é que eles devem ser interoperáveis entre implementações. Em outras palavras, se dois sistemas diferentes estiverem usando uma implementação que esteja em conformidade com a RFC4122, eles (ou pelo menos deveriam ) criarão o mesmo UUID se todas as outras coisas forem iguais (por exemplo, gerar a mesma versão UUID, com o mesmo espaço de nome e o mesmos dados). Essa propriedade pode ser muito útil em algumas situações (especialmente em cenários de armazenamento endereçável por conteúdo), mas talvez não no seu caso particular.
fonte
NAMESPACE_URL
é um UUID geralmente igual a6ba7b811-9dad-11d1-80b4-00c04fd430c8
, seguindo a recomendação feita na página 30 da RFC-4122 .A documentação do Postgres descreve as diferenças entre
UUID
s. Alguns deles:V3:
V4:
fonte