Cela concerne cette question . J'utilise le code ci-dessous à partir de cette réponse pour générer l'UUID en 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);
});
Cette solution semble fonctionner correctement, mais j'obtiens des collisions. Voici ce que j'ai:
- Une application Web fonctionnant dans Google Chrome.
- 16 utilisateurs.
- environ 4000 UUID ont été générés au cours des 2 derniers mois par ces utilisateurs.
- J'ai eu environ 20 collisions - par exemple, le nouvel UUID généré aujourd'hui était le même qu'il y a environ 2 mois (utilisateur différent).
Quelle est la cause de ce problème et comment puis-je l'éviter?
(r&0x3|0x8)
portion / évaluation?Réponses:
Ma meilleure supposition est que
Math.random()
votre système est cassé pour une raison quelconque (aussi étrange que cela puisse paraître). C'est le premier rapport que j'ai vu sur quelqu'un qui aurait des collisions.node-uuid
a un faisceau de test que vous pouvez utiliser pour tester la distribution des chiffres hexadécimaux dans ce code. Si cela semble correct, alors ce n'est pas le casMath.random()
, alors essayez de remplacer l'implémentation UUID que vous utilisez dans lauuid()
méthode et voyez si vous obtenez toujours de bons résultats.[Mise à jour: Je viens de voir le rapport de Veselin sur le bogue
Math.random()
au démarrage. Étant donné que le problème ne se situe qu'au démarrage, ilnode-uuid
est peu probable que le test soit utile. Je commenterai plus en détail le lien devoluk.com.]la source
En effet il y a des collisions mais uniquement sous Google Chrome. Découvrez mon expérience sur le sujet ici
http://devoluk.com/google-chrome-math-random-issue.html
(Lien rompu à partir de 2019. Lien d'archive: https://web.archive.org/web/20190121220947/http://devoluk.com/google-chrome-math-random-issue.html .)
Il semble que les collisions ne se produisent que lors des premiers appels de Math.random. Parce que si vous exécutez simplement la méthode createGUID / testGUIDs ci-dessus (ce qui était évidemment la première chose que j'ai essayée), cela fonctionne simplement sans aucune collision.
Donc, pour faire un test complet, il faut redémarrer Google Chrome, générer 32 octets, redémarrer Chrome, générer, redémarrer, générer ...
la source
Juste pour que les autres puissent en être conscients, je rencontrais un nombre étonnamment élevé de collisions apparentes en utilisant la technique de génération d'UUID mentionnée ici. Ces collisions ont continué même après que je sois passé à seedrandom pour mon générateur de nombres aléatoires. Cela m'a fait arracher les cheveux, comme vous pouvez l'imaginer.
J'ai finalement compris que le problème était (presque?) Exclusivement associé aux robots d'exploration du Web de Google. Dès que j'ai commencé à ignorer les requêtes avec "googlebot" dans le champ user-agent, les collisions ont disparu. Je suppose qu'ils doivent mettre en cache les résultats des scripts JS de manière semi-intelligente, avec pour résultat final que leur navigateur spidering ne peut pas être compté pour se comporter comme le font les navigateurs normaux.
Juste un FYI.
la source
Je voulais publier ceci comme un commentaire à votre question, mais apparemment, StackOverflow ne me le permettra pas.
Je viens de lancer un test rudimentaire de 100000 itérations dans Chrome à l'aide de l'algorithme UUID que vous avez publié et je n'ai eu aucune collision. Voici un extrait de code:
Etes-vous sûr qu'il ne se passe pas autre chose ici?
la source
La réponse qui a initialement publié cette solution UUID a été mise à jour le 28/06/2017:
la source
Les réponses ici traitent de "quelle est la cause du problème?" (Problème de graine Chrome Math.random) mais pas "comment puis-je l'éviter?".
Si vous cherchez toujours comment éviter ce problème, j'ai écrit cette réponse il y a quelque temps en tant que version modifiée de la fonction de Broofa pour contourner ce problème exact. Il fonctionne en décalant les 13 premiers nombres hexadécimaux par une partie hexadécimale de l'horodatage, ce qui signifie que même si Math.random est sur la même graine, il générera toujours un UUID différent à moins d'être généré exactement à la même milliseconde.
la source