Prova simples de que o GUID não é exclusivo [fechado]


323

Gostaria de provar que um GUID não é exclusivo em um programa de teste simples. Eu esperava que o código a seguir funcionasse por horas, mas não está funcionando. Como posso fazer isso funcionar?

BigInteger begin = new BigInteger((long)0);
BigInteger end = new BigInteger("340282366920938463463374607431768211456",10);  //2^128
for(begin; begin<end; begin++)
  Console.WriteLine(System.Guid.NewGuid().ToString());

Eu estou usando c #.


107
Como desenvolvedor de software, o que você diria se um usuário viesse até você e dissesse "não está funcionando"?
21139 JoshJordan

152
Aguarde vários trilhões de anos.
10119 hobbs

67
Modificado porque esta é a coisa mais divertida que eu já vi online hoje.
jrockway

32
@jrockway - lol. Estou tendo problemas para encontrar algo sobre essa questão que não esteja fundamentalmente errado. Quanto mais eu olho para ele, mais engraçado fica.
tylerl

243
É apenas globalmente único, por isso é único no nosso planeta. Se você deseja um ID verdadeiramente exclusivo, precisará usar um ID universalmente exclusivo (UUID). Presumo que você esteja interessado apenas na singularidade dentro do nosso universo. :-)
tvanfosson 10/11/2009

Respostas:


407

Kai, eu forneci um programa que fará o que você deseja usando threads. É licenciado sob os seguintes termos: você deve me pagar $ 0,0001 por hora por núcleo de CPU em que o executa. As taxas são pagas no final de cada mês do calendário. Entre em contato comigo para obter os detalhes da minha conta paypal o quanto antes.

using System;
using System.Collections.Generic;
using System.Linq;

namespace GuidCollisionDetector
{
    class Program
    {
        static void Main(string[] args)
        {
            //var reserveSomeRam = new byte[1024 * 1024 * 100];     // This indeed has no effect.

            Console.WriteLine("{0:u} - Building a bigHeapOGuids.", DateTime.Now);
            // Fill up memory with guids.
            var bigHeapOGuids = new HashSet<Guid>();
            try
            {
                do
                {
                    bigHeapOGuids.Add(Guid.NewGuid());
                } while (true);
            }
            catch (OutOfMemoryException)
            {
                // Release the ram we allocated up front.
                // Actually, these are pointless too.
                //GC.KeepAlive(reserveSomeRam);
                //GC.Collect();
            }
            Console.WriteLine("{0:u} - Built bigHeapOGuids, contains {1} of them.", DateTime.Now, bigHeapOGuids.LongCount());


            // Spool up some threads to keep checking if there's a match.
            // Keep running until the heat death of the universe.
            for (long k = 0; k < Int64.MaxValue; k++)
            {
                for (long j = 0; j < Int64.MaxValue; j++)
                {
                    Console.WriteLine("{0:u} - Looking for collisions with {1} thread(s)....", DateTime.Now, Environment.ProcessorCount);
                    System.Threading.Tasks.Parallel.For(0, Int32.MaxValue, (i) =>
                    {
                        if (bigHeapOGuids.Contains(Guid.NewGuid()))
                            throw new ApplicationException("Guids collided! Oh my gosh!");
                    }
                    );
                    Console.WriteLine("{0:u} - That was another {1} attempts without a collision.", DateTime.Now, ((long)Int32.MaxValue) * Environment.ProcessorCount);
                }
            }
            Console.WriteLine("Umm... why hasn't the universe ended yet?");
        }
    }
}

PS: Eu queria experimentar a biblioteca de extensões paralelas. Essa foi fácil.

E usar OutOfMemoryException como fluxo de controle parece errado.

EDITAR

Bem, parece que isso ainda atrai votos. Por isso, corrigi o problema GC.KeepAlive (). E alterou para rodar com C # 4.

E para esclarecer meus termos de suporte: o suporte está disponível apenas em 28 / fev / 2010. Use uma máquina do tempo para fazer solicitações de suporte apenas naquele dia.

EDIT 2 Como sempre, o GC faz um trabalho melhor do que eu no gerenciamento de memória; quaisquer tentativas anteriores de fazê-lo estavam fadadas ao fracasso.


120
Esse último Console.WriteLine me fez rir muito. Eu acho que você deveria jogar um CommonlyAcceptedCosmologicTheoriesWrongException.
R. Martinho Fernandes

17
marcar isso como Aceito também significa que @Kai aceita os termos estipulados por @ligos?
kb.

3
A configuração reserveSomeRam = null;realmente não realiza nada.
DevinB

4
@devinb por favor explique? parece que está liberando os bytes que foram alocados anteriormente para que o GC possa Collect(). Por que isso não realiza nada?
Mythz

3
GuidCollisionDetector. O nome tem potencial
Ufuk Hacıoğulları

226

Isso funcionará por muito mais que horas. Supondo que ele faça um loop a 1 GHz (o que não ocorrerá - será muito mais lento que isso), ele será executado por 1079028307080601414898970 anos. O que é cerca de 83 bilhões de vezes mais que a idade do universo.

Supondo que a lei de Moores seja válida, seria muito mais rápido não executar esse programa, esperar várias centenas de anos e executá-lo em um computador bilhões de vezes mais rápido. De fato, qualquer programa que demore mais para executar do que leva a velocidade da CPU para dobrar (cerca de 18 meses) será concluído mais cedo se você esperar até que a velocidade da CPU tenha aumentado e comprar uma nova CPU antes de executá-la (a menos que você o escreva para que ele pode ser suspenso e retomado em novo hardware).


27
caramba - então talvez threads de servidor que gerem guias sejam uma idéia melhor?
Kai

107
Quatro threads em um processador quad core o tornariam 20 bilhões de vezes a idade do universo - então sim, isso ajudaria muito.
Rjmunro

34
Suspeito que seja um troll, mas com a possibilidade de não ser: os tópicos não são mágicos. Se você pode executar um bilhão de operações por segundo em um encadeamento, a passagem para dez encadeamentos significa que cada um executa 1/10 com a mesma frequência. Cada encadeamento realiza operações de 100 M por segundo; o número total de operações por segundo não é aumentado. A maneira de aumentar o número de operações por segundo é comprar mais computadores. Suponha que você comprou um bilhão de computadores a mais. Isso reduziria o problema a apenas 10790283070806 anos, o que ainda leva mais de quatro horas.
Eric Lippert

10
Eu acho que o rjmunro está assumindo que cada thread seria executado em um núcleo separado; 83 bilhões de universos / 4 núcleos equivalem aproximadamente a 20 bilhões de universos. Hora de comprar as ações da Intel!
Dour High Arch

4
O @Erik 83 bilhões de processadores significa que você poderá fazer isso na quantidade de tempo que o universo existiu até agora. Então, mesmo isso não é suficiente.
Rjmunro 12/11/2009

170

Um GUID é teoricamente não exclusivo. Aqui está sua prova:

  • GUID é um número de 128 bits
  • Você não pode gerar 2 ^ 128 + 1 ou mais GUIDs sem reutilizar GUIDs antigos

No entanto, se toda a potência do sol fosse direcionada para a execução dessa tarefa, ela esfriaria muito antes de terminar.

Os GUIDs podem ser gerados usando várias táticas diferentes, algumas das quais tomam medidas especiais para garantir que uma determinada máquina não gere o mesmo GUID duas vezes. Encontrar colisões em um algoritmo específico mostraria que seu método específico para gerar GUIDs é ruim, mas não provaria nada sobre GUIDs em geral.


44
Princípio para o resgate!
yfeldblum 10/11/2009

22
Um comentário para o sol frio. Houve um comentário interessante em algum lugar sobre a inutilidade das chaves de criptografia> 256 bits. A iteração sobre todos os valores-chave possíveis exigiria mais energia do que o universo inteiro possui. Alternar um pouco na CPU requer uma pequena quantidade de energia (é o que gera o calor) que, quando multiplicado 2 ^ 256 vezes, é um número realmente grande que excede a energia armazenada no universo, usando E = mc2 o universo precisaria de massa de 2 ^ 227kg, nosso sol é 2 ^ 101kg, então isso é 2 ^ 126 sóis!
Skizz

31
@ Skizz: Isso é verdade apenas para ataques de força bruta. Quando um esquema de criptografia é "quebrado", significa que ele pode ser resolvido em menos tempo que a força bruta, mas o tempo de resolução permanece proporcional ao tamanho da chave.
Steven Sudit 19/05/10

1
@StevenSudit: proporcional ao expoente do tamanho da chave (a menos que P == NP)
Ihar Bury

1
@Orlangur Proporcional ao tamanho da chave medido em bits.
Steven Sudit 20/03/12

137

É claro que os GUIDs podem colidir. Como os GUIDs são de 128 bits, basta gerá- 2^128 + 1los e, pelo princípio do pigeonhole , deve haver uma colisão.

Mas quando dizemos que um GUID é único, o que realmente queremos dizer é que o espaço da chave é tão grande que é praticamente impossível gerar acidentalmente o mesmo GUID duas vezes (supondo que estamos gerando GUIDs aleatoriamente).

Se você gerar uma sequência de nGUIDs aleatoriamente, a probabilidade de pelo menos uma colisão é aproximadamente p(n) = 1 - exp(-n^2 / 2 * 2^128)(esse é o problema do aniversário com o número possível de aniversários 2^128).

   n     p(n)
2^30 1.69e-21
2^40 1.77e-15
2^50 1.86e-10
2^60 1.95e-03

Para tornar esses números concretos 2^60 = 1.15e+18,. Portanto, se você gerar um bilhão de GUIDs por segundo, você levará 36 anos para gerar 2^60GUIDs aleatórios e, mesmo assim, a probabilidade de uma colisão ainda é alta 1.95e-03. É mais provável que você seja assassinado em algum momento da sua vida ( 4.76e-03) do que em uma colisão nos próximos 36 anos. Boa sorte.


239
Se você for assassinado em algum momento de sua vida, é provável que esteja no fim.
Michael Myers

25
@ mmyers: excelente ponto. Isso significa que minhas chances de ser assassinado no momento são absurdamente baixas, pois esse não é o fim da minha vida. Oh, espere ... #
911 Steven Sudit #: 1941

Além disso, se dois GUIDs forem criados dentro de um curto período, as chances de serem usados ​​no mesmo sistema são pequenas. Portanto, isso aumenta a exclusividade.
AMissico

Esses números e referências ao problema do aniversário não têm sentido. Os algoritmos de geração de GUID não geram valores em todo o intervalo com igual probabilidade. De fato, o IIRC, o algoritmo original, usou o endereço MAC do PC gerador + o tempo atual como parte do resultado - o que reduz o risco de colisão com Guids gerados em outros PCs, mas, é claro, reduz o espaço da chave.
Joe

17
Você está assumindo que a probabilidade de ser assassinado é uma constante para todos os seres humanos. Mas claramente as pessoas que escrevem comentários maliciosos nas postagens do fórum são o tipo de pessoas com maior probabilidade de serem assassinadas do que as pessoas comuns.
21411 Jay

61

Se você estiver preocupado com a exclusividade, sempre poderá comprar novos GUIDs para poder jogar fora os antigos. Vou colocar alguns no eBay, se você quiser.


13
Legal - quanto custa o conjunto completo, de 0 a (2 ^ 128) -1?
21310 Steve314

23
À venda, US $ 0,01 por 1k GUIDs. Vou jogar alguns sinos de vento de bambu, se você pedir nos próximos 60 minutos.
Ctacke

7
Meu conjunto é mais exclusivo e de maior qualidade. Eles são verificados e verificados duas vezes, o que faz com que valham US $ 1 por GUID. Você pode até comprá-los em lotes, se não quiser fazer o investimento total de uma só vez. Vou ter que cobrar um extra de US $ 10 por lote embora.
31310 Thomas

3
Vou definir um plano mensal e fornecer orientações ilimitadas pelo preço certo. ^ Esses caras estão tentando enganá-lo e vender guids muito caros. Eu vou lhe vender guias de qualidade fabricados na China!
ErocM

47

Pessoalmente, acho que o "Big Bang" foi causado quando dois GUIDs colidiram.


4
Basta lembrar É preciso um "especial" tipo de programador para fazer isso ...
AnthonyLambert

Eu gostaria de ouvir seu raciocínio com sua teoria. Acho que poderíamos começar uma nova religião com base nisso e recrutar T.Cruise!
ErocM

@ErocM; Consulte "Cosmologia de Brane" ( en.wikipedia.org/wiki/Brane_cosmology ) e "Membrana (Teoria M)" ( en.wikipedia.org/wiki/Membrane_(M-Theory) ). A idéia é que, se duas farinhas tocam, um novo universo é criado. Portanto, você pode deduzir que, se dois GUIDs tocarem, um novo universo será criado.
AMissico

2
Se a Timecop nos ensinou alguma coisa é que o mesmo assunto não pode ocupar o mesmo espaço a qualquer momento. Portanto, se dois GUIDs colidissem, eles se consumiriam e a implosão resultante geraria um buraco negro, devorando todo o universo. Então, na realidade, não criaria um universo, destruirá.
AJC

42

Você pode mostrar isso em O (1) time com uma variante do algoritmo quântico de bogosort .

Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
if(g1 != g2) Universe.Current.Destroy();

21
Estou recebendo uma exceção ao chamar Destroy (). Baseado no texto, acho que meu computador não possui o hardware necessário para destruir o universo atual. Você sabe onde eu posso obtê-lo?
Steven Sudit 19/05/10

11
@Steven: Nah, alguns gerentes ficaram muito preocupados com o quão ruim a API ficaria para o público e determinaram que ela sempre falhasse por "razões de segurança". Se você olhar para a fonte do método não é justo que uma linha: throw new MundaneHardwareException();. Enfim, ouvi dizer que os caras do CERN têm algum tipo de Big Hadron Thingy que pode dar certo ...
R. Martinho Fernandes

7
@ Martinho: Ah, tudo bem. Vou olhar para substituir Universe.Current.Destroy()com Cern.Lhc.DestroyThisUniverse().
Steven Sudit 20/05/10

61
Eu sabia que havia uma razão para ter programado em Haskell. Esses efeitos colaterais estão ficando assustadores.
Edward KMETT

6
"Existe uma teoria que afirma que, se alguém descobrir exatamente para que serve o universo e por que ele está aqui, ele desaparecerá instantaneamente e será substituído por algo ainda mais bizarramente inexplicável. Há outra teoria que afirma que isso já aconteceu". . " - Douglas Adams, o Guia do Mochileiro das Galáxias
Mike Pirnat

28

É provável que quaisquer dois GUIDs sejam únicos (não iguais).

Veja esta entrada do SO e da Wikipedia

Embora não seja garantido que cada GUID gerado seja exclusivo, o número total de chaves exclusivas (2 ^ 128 ou 3,4 × 10 ^ 38) é tão grande que a probabilidade de o mesmo número ser gerado duas vezes é muito pequena. Por exemplo, considere o universo observável, que contém cerca de 5 × 10 ^ 22 estrelas; toda estrela poderia ter 6,8 × 10 ^ 15 GUIDs universalmente únicos.

Então, provavelmente você terá que esperar muitos bilhões de anos e torcer para que acerte um antes do universo, como sabemos que chega ao fim.


então 2 ^ 128 não é o número correto de guias possíveis?
Kai

21
Isto é. Por que você acha que 2 ^ 128 é um número pequeno?
jrockway

Sim, 2 ^ 128 é o número correto de possíveis guias.
Graviton

3
É um número infernal. $ irb >> 2**128 => 340282366920938463463374607431768211456
precisa saber é o seguinte

45
@ Infinito - Mesmo para você?
Austin Richardson

27

[Atualização:] Como os comentários abaixo apontam, os MS GUIDs mais recentes da Microsoft são a V4 e não usam o endereço MAC como parte da geração da GUID (no entanto, não vi nenhuma indicação de uma implementação da V5 da MS, por isso, se alguém tiver um link confirmando que me avise). Porém, com a V4, o tempo ainda é um fator, e as chances de duplicação de GUIDs permanecem tão pequenas que são irrelevantes para qualquer uso prático. Você certamente nunca geraria um GUID duplicado a partir de apenas um teste de sistema, como o OP estava tentando fazer.

A maioria dessas respostas está faltando um ponto vital sobre a implementação do GUID da Microsoft. A primeira parte do GUID é baseada em um registro de data e hora e outra parte é baseada no endereço MAC da placa de rede (ou um número aleatório se nenhuma NIC estiver instalada).

Se eu entendi isso corretamente, significa que a única maneira confiável de duplicar um GUID seria executar gerações GUID simultainousous em várias máquinas onde os endereços MAC eram os mesmos E onde os relógios nos dois sistemas estavam no mesmo momento exato em que a geração ocorreu (o registro de data e hora é baseado em milissegundos, se eu entendi direito) .... mesmo assim, existem muitos outros bits aleatórios no número, portanto as chances ainda são muito pequenas.

Para todos os fins práticos, os GUIDs são universalmente exclusivos.

Há uma descrição muito boa do MS GUID no blog "The Old New Thing"


3
Isso é realmente possível ao usar a virtualização. Você pode e recebe guias duplicados.
Goran

8
Raymond está desatualizado na parte do endereço MAC, porém, a Microsoft não os usa mais. Consulte en.wikipedia.org/wiki/GUID#Algorithm para obter a diferença entre os Guids V1 e V4.
Michael Stum

1
Este não é mais o caso. O atual esquema V5 é apenas 128 bits de pura bondade pseudo-aleatória.
Edward KMETT

engraçado como você declara tudo o que fiz um mês depois de mim e você ganha 16 pontos e ainda tenho 0?
AnthonyLambert

1
Ya Tony, há algo de estranho nisso. Quando respondi à postagem, havia apenas 3 ou 4 respostas, e não me lembrava de ter visto a sua ... se tivesse, teria votado apenas. Normalmente, não respondo perguntas quando já existem outras respostas que o cobrem suficientemente bem (é por isso que provavelmente tenho um representante geral bastante baixo).
Stephen M. Redd

23

Aqui está um pequeno método de extensão bacana que você pode usar se desejar verificar a exclusividade do guia em muitos lugares do seu código.

internal static class GuidExt
{
    public static bool IsUnique(this Guid guid)
    {
        while (guid != Guid.NewGuid())
        { }
        return false;
    }
}

Para chamá-lo, basta chamar Guid.IsUnique sempre que você gerar um novo guid ...

Guid g = Guid.NewGuid();
if (!g.IsUnique())
{
    throw new GuidIsNotUniqueException();
}

... diabos, eu recomendo chamá-lo duas vezes para garantir que ele acertou na primeira rodada.


2
Como isso garante que this guidnunca tenha sido gerado em nenhum outro lugar deste mundo? : p Caramba, precisamos de um pool mundial de guias. :)
Nawfal

19

Contando até 2 ^ 128 - ambicioso.

Vamos imaginar que podemos contar 2 ^ 32 IDs por segundo por máquina - não tão ambicioso, pois nem sequer são 4,3 bilhões por segundo. Vamos dedicar 2 ^ 32 máquinas a essa tarefa. Além disso, vamos obter 2 ^ 32 civilizações para cada uma dedicar os mesmos recursos à tarefa.

Até o momento, podemos contar 2 ^ 96 IDs por segundo, o que significa que contaremos por 2 ^ 32 segundos (um pouco mais de 136 anos).

Agora, tudo o que precisamos é obter 4.294.967.296 civilizações para cada uma dedicar 4.294.967.296 máquinas, cada máquina capaz de contar 4.294.967.296 IDs por segundo, puramente para essa tarefa pelos próximos 136 anos ou mais - sugiro que iniciem essa tarefa essencial agora; -)


17

Bem, se o tempo de execução de 83 bilhões de anos não o assusta, pense que você também precisará armazenar os GUIDs gerados em algum lugar para verificar se você possui uma duplicata; armazenar 2 ^ 128 números de 16 bytes exigiria apenas a alocação de 4951760157141521099596496896 terabytes de RAM antecipadamente, imaginando que você tenha um computador que poderia caber em tudo isso e que de alguma forma encontrará um lugar para comprar DIMMs de terabyte com 10 gramas cada, combinados pesar mais de 8 massas terrestres, para que você possa alterá-lo seriamente da órbita atual, antes mesmo de pressionar "Executar". Pense duas vezes!


12
for(begin; begin<end; begin)
    Console.WriteLine(System.Guid.NewGuid().ToString());

Você não está incrementando, beginportanto a condição begin < endé sempre verdadeira.


1
nenhum - não porque eu pode iterar bigint
Kai

3
Realmente importa se ele faz um loop para sempre versus repetir 340282366920938463463374607431768211456 vezes?
21411 Jay

3
então ... você prefere receber um soco 340282366920938463463374607431768211456 vezes ou para sempre!?!?!?
ErocM 11/11/11

na verdade, é isso que realmente responde à pergunta! e sem votos: p
nawfal 1/12/12


9

Presumivelmente, você tem motivos para acreditar que o algoritmo para produzir Guids não está produzindo números verdadeiramente aleatórios, mas na verdade está alternando com um período << 2 ^ 128.

por exemplo, o método RFC4122 usado para derivar GUIDs que corrigem os valores de alguns bits.

A prova do ciclismo dependerá do tamanho possível do período.

Por pequenos períodos, a tabela de hash (GUID) -> GUID com substituição em caso de colisão, se os GUIDs não corresponderem (terminar se o fizerem), pode ser uma abordagem. Considere também fazer a substituição apenas uma fração aleatória do tempo.

Por fim, se o período máximo entre colisões for grande o suficiente (e não for conhecido antecipadamente), qualquer método só produzirá uma probabilidade de que a colisão seja encontrada se existir.

Observe que, se o método de geração de Guids for baseado no relógio (consulte a RFC), talvez não seja possível determinar se existem colisões, pois (a) você não poderá esperar o tempo suficiente para que o relógio termine, ou (b) você não pode solicitar Guids suficientes dentro de um relógio para forçar uma colisão.

Como alternativa, você poderá mostrar um relacionamento estatístico entre os bits no Guid ou uma correlação de bits entre os Guids. Esse relacionamento pode tornar altamente provável que o algoritmo seja defeituoso sem necessariamente ser capaz de encontrar uma colisão real.

Obviamente, se você só quer provar que o Guids pode colidir, uma prova matemática, não um programa, é a resposta.


8

Não entendo por que ninguém mencionou a atualização da sua placa gráfica ... Certamente, se você tiver uma NVIDIA Quadro FX 4800 de ponta ou algo assim (192 núcleos CUDA), isso seria mais rápido ...

Obviamente, se você pudesse comprar alguns NVIDIA Qadro Plex 2200 S4s (com 960 núcleos CUDA cada), esse cálculo realmente gritaria. Talvez a NVIDIA esteja disposta a emprestar-lhe alguns para uma "demonstração tecnológica" como um truque de relações públicas?

Certamente eles gostariam de fazer parte desse cálculo histórico ...


hmmmm ... eu poderia executá-lo em nossa grade de 10.000 nós no trabalho.
AnthonyLambert

8

Mas você tem que ter certeza que você tem uma duplicata, ou você só se preocupam se não pode ser duplicado. Para ter certeza de que você tem duas pessoas com o mesmo aniversário, precisa de 366 pessoas (sem contar o ano bissexto). Para que haja mais de 50% de chance de ter duas pessoas com o mesmo aniversário, você precisa apenas de 23 pessoas. Esse é o problema do aniversário .

Se você tiver 32 bits, precisará apenas de 77.163 valores para ter uma chance maior que 50% de duplicar. Experimente:

Random baseRandom = new Random(0);

int DuplicateIntegerTest(int interations)
{
    Random r = new Random(baseRandom.Next());
    int[] ints = new int[interations];
    for (int i = 0; i < ints.Length; i++)
    {
        ints[i] = r.Next();
    }
    Array.Sort(ints);
    for (int i = 1; i < ints.Length; i++)
    {
        if (ints[i] == ints[i - 1])
            return 1;
    }
    return 0;
}

void DoTest()
{
    baseRandom = new Random(0);
    int count = 0;
    int duplicates = 0;
    for (int i = 0; i < 1000; i++)
    {
        count++;
        duplicates += DuplicateIntegerTest(77163);
    }
    Console.WriteLine("{0} iterations had {1} with duplicates", count, duplicates);
}

1000 iterations had 737 with duplicates

Agora, 128 bits são muitos, então você ainda está falando de um grande número de itens, ainda com poucas chances de colisão. Você precisaria do seguinte número de registros para as probabilidades especificadas usando uma aproximação:

  • 0,8 bilhões de bilhões para uma chance de 1/1000 de colisão
  • 21,7 bilhões de bilhões para 50% de chance de uma colisão
  • 39,6 bilhões de bilhões, com 90% de chance de colisão

Há cerca de 1E14 e-mails enviados por ano, então levaria cerca de 400.000 anos nesse nível antes que você tivesse 90% de chance de ter dois com o mesmo GUID, mas isso é muito diferente de dizer que você precisa executar um computador 83 bilhões vezes a idade do universo ou que o sol esfriaria antes de encontrar uma duplicata.


7

Vocês não estão perdendo um ponto importante?

Eu pensei que os GUIDs fossem gerados usando duas coisas que aumentam as chances de serem Globalmente únicos. Uma é que elas são propagadas com o endereço MAC da máquina em que você está e duas usam o tempo em que foram geradas mais um número aleatório.

Portanto, a menos que você o execute na máquina real e execute todas as suas suposições dentro do menor período de tempo que a máquina use para representar um tempo no GUID, você nunca gerará o mesmo número, independentemente de quantas suposições você usar usando a chamada do sistema.

Eu acho que se você souber a maneira como um GUID é feito, na verdade, reduzirá o tempo para adivinhar bastante.

Tony


3
Nem todos os GUIDs são criados dessa maneira. Mesmo que existissem, Kai precisa esperar apenas até que o carimbo de data / hora usado para criar o GUID atinja um número suficiente de vezes para que um usado para criar um GUID seja usado novamente.
Dour High Arch

3
Os guias não são baseados no endereço mac desde 2000 ou 2001. Como um dos service packs para NT4 e / ou Win2k, eles mudaram completamente o algoritmo. Agora eles são gerados por um gerador de números aleatórios, menos alguns bits que identificam que tipo de guia é esse.
precisa

4
nem todos os GUIDs vêm de plataformas Windows ...
AnthonyLambert

O OP menciona C #, então é o Windows. Além disso, o V4 GUID é apenas para Windows?
Steven Sudit 19/05/10

5
@Martinho: Ah, mas o teste de unidade de Mono para Guid, no GuidTest.cs, contém um método que cria dois novos GUIDs e verifica a igualdade, falhando se forem iguais. À medida que o Mono cria com sucesso, podemos ter certeza absoluta de que seus GUIDs são únicos! :-)
Steven Sudit

6

Você pode fazer o hash dos GUIDs. Dessa forma, você deve obter um resultado muito mais rápido.

Ah, é claro, executar vários threads ao mesmo tempo também é uma boa idéia, dessa forma você aumentará a chance de uma condição de corrida gerar o mesmo GUID duas vezes em threads diferentes.


6

Os GUIDs são 124 bits porque 4 bits mantêm o número da versão.


o motivo de não adicionar isso como comentário: ninguém o mencionou, e eu não sei para quem devo dizer isso :) #
Behrooz

Hooooraaaay eu fiz isso. Em algum aplicativo "real" que eu escrevi, eu tive uma colisão Guid em uma tabela com ~ 260k Rows. (MSSQL 2008 R2 Express).
Behrooz 27/02

6
  1. Vá para o laboratório de criogenia na cidade de Nova York.
  2. Congele-se por (aproximadamente) 1990 anos.
  3. Consiga um emprego na Planet Express.
  4. Compre uma CPU totalmente nova. Construa um computador, execute o programa e coloque-o no local seguro com uma máquina de movimento pseudo-perpétua como a máquina do dia do juízo final.
  5. Aguarde até que a máquina do tempo seja inventada.
  6. Ir para o futuro usando a máquina do tempo. Se você comprou uma CPU de 128 bits de 1YHz, vá para 3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 psdepois em que você começou a executar o programa.
  7. ...?
  8. LUCRO!!!

... Demora pelo menos 10,783,127anos, mesmo se você tivesse uma CPU de 1YHz 1,000,000,000,000,000(ou 1,125,899,906,842,624se preferir usar prefixo binário) vezes mais rápida que a CPU de 1GHz.

Portanto, em vez de esperar que a computação terminasse, seria melhor alimentar pombos que perderam o lar porque outros npombos o levaram para casa. :(

Ou você pode esperar até que o computador quântico de 128 bits seja inventado. Em seguida, você pode provar que o GUID não é exclusivo, usando seu programa em um tempo razoável (talvez).


Eu estava esperando por uma referência de super-herói nesta resposta - falha por cartaz: p - incrível, no entanto.
IbrarMumtaz

4

Você já tentou begin = begin + new BigInteger((long)1)no lugar do begin ++?


2
ninguém votou a favor da resposta que realmente responde à pergunta: P
Nawfal

4

Se o número de UUID sendo gerado seguir a lei de Moore, a impressão de nunca ficar sem GUID no futuro próximo é falsa.

Com 2 ^ 128 UUIDs, levará apenas 18 meses * Log2 (2 ^ 128) ~ = 192 anos, antes de ficarmos sem todos os UUIDs.

E acredito (sem qualquer prova estatística) nos últimos anos desde a adoção em massa do UUID, a velocidade que estamos gerando está aumentando muito mais rapidamente do que a lei de Moore dita. Em outras palavras, provavelmente temos menos de 192 anos até termos que lidar com a crise de UUID, muito mais cedo que o fim do universo.

Mas como definitivamente não os esgotaremos até o final de 2012, deixaremos para outras espécies se preocupar com o problema.


3

As chances de um bug no código de geração de GUID são muito maiores do que as chances do algoritmo de gerar uma colisão. As chances de um bug no seu código para testar os GUIDs são ainda maiores. Desistir.


2

O programa, embora com erros, mostra a prova de que um GUID não é exclusivo. Aqueles que tentam provar o contrário estão perdendo o ponto. Esta declaração apenas prova a fraca implementação de algumas variações do GUID.

Um GUID não é necessário exclusivo por definição, é altamente exclusivo por definição. Você acabou de refinar o significado de altamente. Dependendo da versão, o implementador (MS ou outros), o uso de VMs, etc., sua definição de grandes alterações. (veja o link no post anterior)

Você pode encurtar sua tabela de 128 bits para provar seu ponto. A melhor solução é usar uma fórmula de hash para encurtar sua tabela com duplicatas e, em seguida, usar o valor total quando o hash colidir e com base nessa gerar novamente um GUID. Se estiver executando em locais diferentes, você armazenará seus pares de chaves hash / completas em um local central.

Ps: se o objetivo é apenas gerar x número de valores diferentes, crie uma tabela de hash dessa largura e verifique o valor do hash.


2

Para não fazer p ** s na fogueira aqui, mas isso realmente acontece, e sim, eu entendo a piada que você está dando a esse cara, mas o GUID é único apenas em princípio, eu me deparei com este tópico porque há um bug no emulador WP7, o que significa que toda vez que ele inicializa, o mesmo GUID é emitido na primeira vez em que é chamado! Então, onde teoricamente você não pode ter um conflito, se houver um problema ao gerar a referida GUI, poderá obter duplicatas

http://forums.create.msdn.com/forums/p/92086/597310.aspx#597310


1

Como parte da geração Guid é baseada no tempo atual da máquina, minha teoria para obter um Guid duplicado é:

  1. Execute uma instalação limpa do Windows
  2. Crie um script de inicialização que redefina o horário para 01-01-2010 12:00:00, assim como o Windows é inicializado.
  3. Logo após o script de inicialização, ele aciona seu aplicativo para gerar um Guid.
  4. Clone esta instalação do Windows, para descartar diferenças sutis que possam ocorrer em inicializações subsequentes.
  5. Imagem de novo o disco rígido com esta imagem e inicialize a máquina algumas vezes.

0

Para mim .. o tempo que leva para um único núcleo gerar um UUIDv1 garante que ele será único. Mesmo em uma situação com vários núcleos, se o gerador de UUID permitir apenas que um UUID seja gerado por vez para seu recurso específico (lembre-se de que vários recursos podem utilizar totalmente os mesmos UUIDs, por mais improvável que seja o recurso inerente ao endereço), você terá UUIDs mais que suficientes para durar até que o carimbo de data / hora se esgote. Nesse ponto, eu realmente duvido que você se importaria.


0

Aqui está uma solução também:

int main()
{
  QUuid uuid;
  while ( (uuid = QUuid::createUuid()) != QUuid::createUuid() ) { }
  std::cout << "Aha! I've found one! " << qPrintable( uuid.toString() ) << std::endl;
}

Nota: requer Qt, mas eu garanto que, se você deixar funcionar por tempo suficiente, ele poderá encontrar um.

(Nota: na verdade, agora que estou olhando para ele, pode haver algo sobre o algoritmo de geração que evita que dois uuids gerados subseqüentemente colidam - mas eu duvido).


0

A única solução para provar que os GUIDs não são exclusivos seria ter um pool mundial de GUIDs. Sempre que um GUID é gerado em algum lugar, ele deve ser registrado na organização. Ou ainda, podemos incluir uma padronização de que todos os geradores de GUID precisam registrá-lo automaticamente e para isso precisam de uma conexão ativa com a Internet!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.