368 Stimmen

Wie gut ist Java's UUID.randomUUID?

Ich weiß, dass zufällige UUIDs in der Theorie eine sehr, sehr, sehr geringe Kollisionswahrscheinlichkeit haben, aber ich frage mich, wie gut Java's randomUUID() in der Praxis ist, um Kollisionen zu vermeiden? Hat jemand Erfahrungen zu teilen?

15 Stimmen

In meiner Erfahrung habe ich noch nie eine Kollision gesehen ;-)

4 Stimmen

Die Algorithmen sind in RFC1422 spezifiziert: ietf.org/rfc/rfc4122.txt

9 Stimmen

@skaffman: Das RFC sagt überhaupt nichts über den verwendeten Algorithmus zur Generierung der Zufallszahlen aus.

196voto

Michael Borgwardt Punkte 334642

UUID verwendet java.security.SecureRandom, das als "kryptografisch stark" gilt. Während die tatsächliche Implementierung nicht spezifiziert ist und zwischen den JVMs variieren kann (was bedeutet, dass alle konkreten Aussagen nur für eine bestimmte JVM gültig sind), schreibt sie jedoch vor, dass die Ausgabe einen statistischen Zufallszahlengenerator-Test bestehen muss.

Es ist immer möglich, dass eine Implementierung subtile Bugs enthält, die all dies zerstören (siehe OpenSSH-Schlüsselgenerierungsfehler), aber ich glaube nicht, dass es einen konkreten Grund gibt, sich um die Zufälligkeit von Java-UUIDs zu sorgen.

41 Stimmen

Es ist immer möglich, dass eine Implementierung subtile Fehler enthält ... - Oder (eine Aluhut aufsetzend) ... absichtliche subtile Mängel. <:-)

31 Stimmen

Die kryptografische Stärke ist für die Frage von Kollisionen völlig irrelevant.

19 Stimmen

@osa: Das Nichtproduzieren von Kollisionen (mehr als bei perfekter Zufälligkeit zu erwarten ist) ist so ziemlich die niedrigste Qualitätserfordernis für einen Zufallszahlengenerator, während kryptographische Stärke die höchste ist. Mit anderen Worten, ein kryptographisch starker Zufallszahlengenerator wird auf jeden Fall nicht mehr Kollisionen produzieren als erwartet.

132voto

sheki Punkte 8491

Wikipedia hat eine sehr gute Antwort http://de.wikipedia.org/wiki/Universally_unique_identifier#Collisions

die Anzahl der zufälligen Version-4-UUIDs, die generiert werden müssen, um eine Wahrscheinlichkeit von mindestens 50% für mindestens eine Kollision zu haben, beträgt 2,71 Billiarden, berechnet wie folgt:

...

Diese Zahl entspricht der Generierung von 1 Milliarde UUIDs pro Sekunde für etwa 85 Jahre, und eine Datei mit so vielen UUIDs, 16 Bytes pro UUID, wäre etwa 45 Exabytes groß, viele Male größer als die derzeit größten Datenbanken, die im Bereich von Hunderten von Petabytes liegen.

...

Also müssen zur Wahrscheinlichkeit von eins zu einer Milliarde 103 Billionen Version-4-UUIDs generiert werden.

68 Stimmen

Ich würde auch von dieser Seite zitieren: "Die Wahrscheinlichkeit für ein Duplikat läge bei etwa 50%, wenn jeder Mensch auf der Erde 600 Millionen UUIDs besitzt."

30 Stimmen

Das gilt nur für echte Zufallszahlen, nicht für Pseudozufallszahlen wie Javas UUIDs.

9 Stimmen

@Markus: völlig falsch. Die Wahrscheinlichkeit von Kollisionen für gute Pseudozufallszahlengeneratoren, insbesondere kryptographisch starke, unterscheidet sich nicht von "echter" Zufälligkeit.

76voto

Stephen C Punkte 665668

Hat jemand Erfahrung zu teilen?

Es gibt 2^122 mögliche Werte für eine Typ-4 UUID. (Die Spezifikation besagt, dass Sie 2 Bits für den Typ und weitere 4 Bits für eine Versionsnummer verlieren.)

Angenommen, Sie würden 1 Million zufällige UUIDs pro Sekunde generieren, wären die Chancen, dass in Ihrem Leben eine Duplikat auftritt, verschwindend gering. Und um das Duplikat zu erkennen, müssten Sie das Problem lösen, 1 Million neue UUIDs pro Sekunde mit _allen zu vergleichen, die Sie zuvor generiert haben_1!

Die Chancen, dass jemand in der Realität ein Duplikat erlebt hat (d.h. es tatsächlich bemerkt hat), sind noch kleiner als verschwindend gering ... wegen der praktischen Schwierigkeit, nach Kollisionen zu suchen.

Natürlich werden Sie in der Regel einen Pseudo-Zufallszahlengenerator verwenden, nicht eine Quelle von wirklich zufälligen Zahlen. Aber ich denke, wir können sicher sein, dass, wenn Sie einen glaubwürdigen Anbieter für Ihre kryptographisch sicheren Zufallszahlen verwenden, dann wird es kryptographische Stärke haben, und die Wahrscheinlichkeit von Wiederholungen wird die gleiche sein wie bei einem idealen (nicht verzerrten) Zufallszahlengenerator.

Wenn Sie jedoch einen JVM mit einem "fehlerhaften" krypto- zufallszahlengenerator verwenden würden, sind alle Wetten abgeschaltet. (Und das könnte auch einige der Workarounds für "Mangel an Entropie" -Probleme auf einigen Systemen einschließen. Oder die Möglichkeit, dass jemand Ihr JRE manipuliert hat, entweder auf Ihrem System oder weiter oben.)


1 - Unter der Annahme, dass Sie "irgendeine Art von binärem btree" verwenden, wie von einem anonymen Kommentator vorgeschlagen, wird jede UUID O(NlogN) Bits RAM-Speicher benötigen, um N verschiedene UUIDs bei niedriger Dichte und zufälliger Verteilung der Bits darzustellen. Multiplizieren Sie das jetzt mit 1.000.000 und der Anzahl der Sekunden, die Sie das Experiment durchführen werden. Ich glaube nicht, dass dies praktisch ist für die Dauer, die benötigt wird, um Kollisionen eines hochwertigen RNG zu testen. Nicht einmal mit (hypothetischen) klugen Darstellungen.

5 Stimmen

"(Und um das Duplikat zu erkennen, müssten Sie das Problem lösen, 1 Million neue UUIDs pro Sekunde mit allen zu vergleichen, die zuvor generiert wurden!)" - dieser Teil ist relativ unkompliziert, vorausgesetzt, Sie haben Ihre UUIDs in einer Art binärer Baumstruktur gespeichert, es wäre einfach nur ein Baumabstieg pro neuer UUID. Sie müssten sie nicht tatsächlich individuell mit allen zuvor generierten UUIDs vergleichen.

0 Stimmen

"Die Wahrscheinlichkeit, dass in Ihrem Leben ein Duplikat auftritt, wäre verschwindend gering", wofür werden uns zukünftige Generationen verurteilen...

0 Stimmen

Vielleicht würden sie uns verurteilen für die Annahme, dass es unrealistisch ist, 10^6 eindeutige IDs pro Sekunde zu generieren. Oder 10^12. Oder dass vielleicht nicht erkennen, dass es so etwas wie eine Zufallszahl nicht gibt. Oder etwas anderes, das schwer vorstellbar ist. Aber ... hey ... die Menschen urteilen schon seit Ewigkeiten über ihre Vorfahren, und es hat nichts geändert.

21voto

sfussenegger Punkte 34431

Ich bin kein Experte, aber ich würde annehmen, dass im Laufe der Jahre genügend kluge Menschen den Zufallszahlengenerator von Java betrachtet haben. Daher würde ich auch annehmen, dass zufällige UUIDs gut sind. Sie sollten also wirklich die theoretische Kollisionswahrscheinlichkeit haben (die etwa 1 : 3 × 10^38 für alle möglichen UUIDs beträgt. Weiß jemand, wie sich das für nur zufällige UUIDs ändert? Ist es 1/(16*4) des oben Genannten?)

Aus meiner praktischen Erfahrung habe ich bisher noch keine Kollisionen gesehen. Ich werde wahrscheinlich einen erstaunlich langen Bart haben, wenn ich meine erste bekomme ;)

11 Stimmen

Von Wikipedia: ... Mit anderen Worten, nur nachdem für die nächsten 100 Jahre jeden Tag 1 Milliarde UUIDs generiert wurden, wäre die Wahrscheinlichkeit, nur ein Duplikat zu erstellen, etwa 50%.

1 Stimmen

Eigentlich sagt Wikipedia, dass es für die nächsten 85 Jahre ist... Ich sage, darauf würde ich mich nicht verlassen, irgendjemand hat irgendwo die gleiche UUID wie du generiert.

14voto

erickson Punkte 256579

Viele der Antworten befassen sich damit, wie viele UUIDs generiert werden müssten, um eine 50%ige Chance auf eine Kollision zu erreichen. Aber eine 50%, 25% oder sogar 1%ige Kollisionschance ist für eine Anwendung, in der Kollision praktisch unmöglich sein muss, wertlos.

Weisen Programmierer routinemäßig andere Ereignisse als "unmöglich" ab, die tatsächlich eintreten können?

Wenn wir Daten auf eine Festplatte oder in den Speicher schreiben und sie dann wieder auslesen, nehmen wir selbstverständlich an, dass die Daten korrekt sind. Wir verlassen uns auf die Fehlerkorrektur des Geräts, um jede Beschädigung zu erkennen. Aber die Chance auf unerkannte Fehler liegt tatsächlich bei etwa 2-50.

Wäre es nicht sinnvoll, einen ähnlichen Standard auf zufällige UUIDs anzuwenden? Wenn Sie dies tun, werden Sie feststellen, dass eine "unmögliche" Kollision in einer Sammlung von rund 100 Milliarden zufälligen UUIDs (236.5) möglich ist.

Dies ist eine astronomische Zahl, aber Anwendungen wie die Aufschlüsselung von Rechnungen in einem nationalen Gesundheitssystem oder das Protokollieren von hochfrequenten Sensordaten auf einer großen Anzahl von Geräten könnten definitiv an diese Grenzen stoßen. Wenn Sie gerade den nächsten Per Anhalter durch die Galaxis schreiben, versuchen Sie nicht, jedem Artikel UUIDs zuzuweisen!

0 Stimmen

Als Vergleichsmaßstab beträgt die Gewinnchance für einen Powerball-Jackpot 1 zu 300 Millionen, aber der Verkauf von 10 bis 20 Millionen Tickets ist typisch. Der Punkt ist, dass viele Leute "unmöglich" als etwas definieren, das weniger als eine Chance von Hunderten Millionen ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X