2014-01-08 13 views
11

Ich versuche Sitzungstoken für meine REST-API zu erstellen. Jedes Mal, wenn die Benutzer anmeldet mir ein neues Token vonGibt randomUUID eine eindeutige ID?

UUID token = UUID.randomUUID(); 
user.setSessionId(token.toString()); 
Sessions.INSTANCE.sessions.put(user.getName(), user.getSessionId()); 

jedoch erschaffe, bin ich nicht sicher, wie gegen doppelten sessionTokens zu schützen.

Zum Beispiel: Kann es ein Szenario, wenn benutzer1 Zeichen und ein Token 87955dc9-d2ca-4f79-b7c8-b0223a32532a und user2 Zeichen bekommen und bekommt auch ein Token 87955dc9-d2ca-4f79-b7c8-b0223a32532a.

Gibt es einen besseren Weg, dies zu tun?

+0

'randomUUID()' kollidiert nicht sehr oft. –

Antwort

24

Wenn Sie eine UUID-Kollision erhalten, gehen Sie als nächstes zur Lotterie.

Aus Wikipedia:

Zufällig generierte UUID haben 122 Zufallsbits. Von insgesamt 128 Bits werden vier Bits für die Version ('Randomly generated UUID'), und zwei Bits für die Variante ('Leach-Salz') verwendet.

Mit zufälligen UUIDs kann die Chance von zwei mit dem gleichen Wert unter Verwendung Wahrscheinlichkeitstheorie (Birthday Paradox) berechnet werden. Unter Verwendung der Approximation

p(n)\approx 1-e^{-\tfrac{n^2}{{2x}}}

das sind die Wahrscheinlichkeiten eines zufälligen Zusammenprall nach n UUIDs Berechnung mit x = 2122:

n Wahrscheinlichkeits 68.719.476.736 = 236 0,0000000000000004 (4 × 10-16) 2.199.023.255.552 = 241 0,0000000000004 (4 × 10-13) 70.368.744.177.664 = 246 0,0000000004 (4 × 10-10)

Um diese Zahlen in der richtigen Perspektive, Das jährliche Risiko einer Person von einem Meteoriten getroffen wird geschätzt in 17 Milliarden eine Chance zu sein, was die Wahrscheinlichkeit bedeutet, ist etwa ,00000000006 (6 × 10-11), was die Chancen von einigen zehn Billionen Schaffung > UUIDs in einem Jahr und mit einem Duplikat. In anderen Worten, erst nach Erzeugung 1000000000 UUIDs jede Sekunde für die nächsten 100 Jahre, schafft die Wahrscheinlichkeit nur duplizieren einen würde etwa 50% betragen. Die Wahrscheinlichkeit eines Duplikats wäre ungefähr 50%, wenn jede Person auf der Erde 600 Millionen UUIDs besitzt.

+0

Und was ist mit einer Cluster-Umgebung? – Nico

+0

Nun, in Zeiten von Big Data kann dies leicht passieren .. – ralfbecher

+2

Die ursprüngliche Frage war im Zusammenhang mit Identifikatoren für eine REST API. Wenn Sie "Zehntausende" von Sitzungen in Ihrer API generieren, ja, dann könnten Kollisionen ein Problem sein, aber ich würde wetten, dass Sie zuerst andere Probleme haben werden. –

4

Oracle-UUID-Dokument. http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html

Sie verwenden diesen Algorithmus aus der Internet Engineering Task Force. http://www.ietf.org/rfc/rfc4122.txt

Ein Zitat aus dem abstrakt.

Ein UUID ist 128 Bit lang und kann Garantie Einzigartigkeit über Raum und Zeit.

Während die Zusammenfassung eine Garantie beansprucht, gibt es nur 3.4 x 10^38 Kombinationen. CodeChimp

+5

Garantie ist ein starkes Wort. –

+1

Das ist ein Zitat aus dem Abstract des verwendeten Algorithmus. Nicht meine Worte. – SethB

+1

Das wären '(2^128) -1' mögliche Werte oder 340,282,366,920,938,463,463,374,607,431,768,211,455. Dennoch ist es "möglich", dass es eine Kollision gibt, aber Sie hätten eine Chance von 1 in (2^128) -1, was bedeutet, dass der verwendete Algorithmus anständig war. Das ist keine sehr gute Chance. – CodeChimp

1

Da eine UUID eine endliche Größe hat, gibt es keine Möglichkeit, über Raum und Zeit hinweg eindeutig zu sein.

Wenn Sie eine UUID benötigen, die innerhalb eines sinnvollen Anwendungsfalles eindeutig ist, können Sie Uuid.getTimeBasedUuid() von Log4j 2 verwenden. Es ist garantiert für etwa 8.900 Jahre einzigartig, solange Sie weniger als 10.000 UUIDs pro Millisekunde generieren.