Isso se relaciona com esta questão . Estou usando o código abaixo de desta resposta para gerar UUID em JavaScript:
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
Esta solução parecia estar funcionando bem, mas estou recebendo colisões. Aqui está o que eu tenho:
- Um aplicativo da web em execução no Google Chrome.
- 16 usuários.
- cerca de 4.000 UUIDs foram gerados nos últimos 2 meses por esses usuários.
- Tive cerca de 20 colisões - por exemplo, o novo UUID gerado hoje era o mesmo de cerca de 2 meses atrás (usuário diferente).
O que está causando esse problema e como posso evitá-lo?
javascript
random
uuid
collision
Muxa
fonte
fonte
(r&0x3|0x8)
porção / avaliação?Respostas:
Meu melhor palpite é que
Math.random()
seu sistema está quebrado por algum motivo (por mais bizarro que isso pareça). Este é o primeiro relatório que vejo de alguém sofrendo colisões.node-uuid
tem um equipamento de teste que você pode usar para testar a distribuição de dígitos hexadecimais nesse código. Se isso parecer certo, então não estáMath.random()
, então tente substituir a implementação UUID que você está usando nouuid()
método lá e veja se você ainda obtém bons resultados.[Atualização: acabei de ver o relatório do Veselin sobre o bug com
Math.random()
na inicialização. Como o problema está apenas na inicialização, onode-uuid
teste provavelmente não será útil. Vou comentar com mais detalhes no link devoluk.com.]fonte
Na verdade, existem colisões, mas apenas no Google Chrome. Confira minha experiência no assunto aqui
http://devoluk.com/google-chrome-math-random-issue.html
(Link quebrado em 2019. Link do arquivo: https://web.archive.org/web/20190121220947/http://devoluk.com/google-chrome-math-random-issue.html .)
Parece que as colisões acontecem apenas nas primeiras chamadas de Math.random. Porque se você apenas executar o método createGUID / testGUIDs acima (que obviamente foi a primeira coisa que tentei), ele funciona sem qualquer tipo de colisão.
Então, para fazer um teste completo, é necessário reiniciar o Google Chrome, gerar 32 bytes, reiniciar o Chrome, gerar, reiniciar, gerar ...
fonte
Só para que outras pessoas possam saber disso - eu estava enfrentando um número surpreendentemente grande de colisões aparentes usando a técnica de geração de UUID mencionada aqui. Essas colisões continuaram mesmo depois que eu mudei para seedrandom para meu gerador de números aleatórios. Isso me fez arrancar os cabelos, como você pode imaginar.
Acabei descobrindo que o problema estava (quase?) Exclusivamente associado aos bots rastreadores da web do Google. Assim que comecei a ignorar as solicitações com "googlebot" no campo do agente do usuário, as colisões desapareceram. Estou supondo que eles devem armazenar em cache os resultados dos scripts JS de alguma forma semi-inteligente, com o resultado final de que seu navegador spidering não pode ser considerado para se comportar da maneira que os navegadores normais fazem.
Apenas um FYI.
fonte
Eu queria postar isso como um comentário à sua pergunta, mas aparentemente o StackOverflow não permite.
Acabei de executar um teste rudimentar de 100.000 iterações no Chrome usando o algoritmo UUID que você postou e não tive colisões. Aqui está um snippet de código:
Tem certeza de que não há mais nada acontecendo aqui?
fonte
A resposta que postou originalmente esta solução UUID foi atualizada em 28/06/2016:
fonte
As respostas aqui tratam de "o que está causando o problema?" (Chrome Math.random seed issue), mas não "como posso evitá-lo?".
Se você ainda está procurando como evitar esse problema, escrevi esta resposta há algum tempo como uma versão modificada da função do Broofa para contornar esse problema exato. Ele funciona compensando os primeiros 13 números hexadecimais por uma porção hexadecimal do carimbo de data / hora, o que significa que, mesmo que Math.random esteja na mesma semente, ele ainda gerará um UUID diferente, a menos que seja gerado no mesmo milissegundo.
fonte