Dies bezieht sich auf diese Frage . Ich verwende den folgenden Code aus dieser Antwort , um eine UUID in JavaScript zu generieren:
'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);
});
Diese Lösung schien gut zu funktionieren, aber ich bekomme Kollisionen. Folgendes habe ich:
- Eine Web-App, die in Google Chrome ausgeführt wird.
- 16 Benutzer.
- In den letzten 2 Monaten wurden von diesen Benutzern etwa 4000 UUIDs generiert.
- Ich habe ungefähr 20 Kollisionen erhalten - z. B. war die heute generierte neue UUID dieselbe wie vor ungefähr 2 Monaten (anderer Benutzer).
Was verursacht dieses Problem und wie kann ich es vermeiden?
javascript
random
uuid
collision
Muxa
quelle
quelle
(r&0x3|0x8)
Teil / Bewertung?Antworten:
Meine beste Vermutung ist, dass
Math.random()
Ihr System aus irgendeinem Grund kaputt ist (so bizarr das klingt). Dies ist der erste Bericht, den ich über Kollisionen von Personen gesehen habe.node-uuid
verfügt über ein Testkabel , mit dem Sie die Verteilung von Hex-Ziffern in diesem Code testen können. Wenn das in Ordnung aussieht, ist dies nicht der Fall.Math.random()
Versuchen Sie also, die von Ihnen verwendete UUID-Implementierung durch die dortigeuuid()
Methode zu ersetzen, und prüfen Sie, ob Sie immer noch gute Ergebnisse erzielen.[Update: Ich habe gerade Veselins Bericht über den Fehler
Math.random()
beim Start gesehen. Da das Problem erst beim Start auftritt,node-uuid
ist es unwahrscheinlich, dass der Test nützlich ist. Ich werde den Link devoluk.com genauer kommentieren.]quelle
In der Tat gibt es Kollisionen, aber nur unter Google Chrome. Schauen Sie sich hier meine Erfahrungen zu diesem Thema an
http://devoluk.com/google-chrome-math-random-issue.html
(Link ab 2019 defekt. Archivlink: https://web.archive.org/web/20190121220947/http://devoluk.com/google-chrome-math-random-issue.html .)
Es scheint, als würden Kollisionen nur bei den ersten Aufrufen von Math.random auftreten. Denn wenn Sie nur die oben beschriebene Methode createGUID / testGUIDs ausführen (was offensichtlich das erste war, was ich versucht habe), funktioniert sie einfach ohne jegliche Kollisionen.
Um einen vollständigen Test durchzuführen, muss Google Chrome neu gestartet, 32 Byte generiert, Chrome neu gestartet, generiert, neu gestartet, generiert werden ...
quelle
Nur damit andere sich dessen bewusst werden können - ich bin mit der hier erwähnten UUID-Generierungstechnik auf eine überraschend große Anzahl offensichtlicher Kollisionen gestoßen. Diese Kollisionen setzten sich fort, selbst nachdem ich für meinen Zufallszahlengenerator auf Seedrandom umgestellt hatte . Das hat mich dazu gebracht, mir die Haare auszureißen, wie Sie sich vorstellen können.
Ich fand schließlich heraus, dass das Problem (fast?) Ausschließlich mit den Webcrawler-Bots von Google zusammenhängt. Sobald ich anfing, Anfragen mit "googlebot" im Feld "User-Agent" zu ignorieren, verschwanden die Kollisionen. Ich vermute, dass sie die Ergebnisse von JS-Skripten auf halbintelligente Weise zwischenspeichern müssen, mit dem Endergebnis, dass man sich nicht darauf verlassen kann, dass sich ihr Spidering-Browser so verhält, wie es normale Browser tun.
Nur zu Ihrer Information.
quelle
Ich wollte dies als Kommentar zu Ihrer Frage posten, aber anscheinend lässt mich StackOverflow nicht.
Ich habe gerade einen rudimentären Test mit 100.000 Iterationen in Chrome mit dem von Ihnen veröffentlichten UUID-Algorithmus durchgeführt und keine Kollisionen festgestellt. Hier ist ein Code-Snippet:
Sind Sie sicher, dass hier nichts anderes los ist?
quelle
Die Antwort , die diese UUID-Lösung ursprünglich veröffentlicht hat, wurde am 28.06.2017 aktualisiert:
quelle
Die Antworten hier beziehen sich auf "Was verursacht das Problem?" (Chrome Math.random Seed-Problem), aber nicht "Wie kann ich das vermeiden?".
Wenn Sie immer noch nach Möglichkeiten suchen, dieses Problem zu vermeiden, habe ich diese Antwort vor einiger Zeit als modifizierte Version von Broofas Funktion geschrieben, um genau dieses Problem zu umgehen. Es funktioniert, indem die ersten 13 Hex-Zahlen um einen Hex-Teil des Zeitstempels versetzt werden. Dies bedeutet, dass selbst wenn sich Math.random auf demselben Startwert befindet, eine andere UUID generiert wird, sofern sie nicht genau in derselben Millisekunde generiert wird.
quelle