Welche UUID-Version soll verwendet werden?

332

Welche Version der UUID sollten Sie verwenden? Ich habe viele Threads gesehen, in denen erklärt wurde, was jede Version beinhaltet, aber ich habe Probleme herauszufinden, was für welche Anwendungen am besten ist.

user1802143
quelle
2
Was sind deine Entscheidungen?
Gabe
Alles, was mit Python funktioniert. Ich denke also, dass docs.python.org/2/library/uuid.html . 1,3,4,5.
user1802143
Wenn Sie neugierig auf die Versionen 3 und 5 sind, lesen Sie diese Frage, Generieren der v5-UUID. Was ist Name und Namespace? .
Basil Bourque

Antworten:

414

Es gibt zwei verschiedene Möglichkeiten, eine UUID zu generieren.

Wenn Sie nur eine eindeutige ID benötigen, möchten Sie eine Version 1 oder Version 4.

  • Version 1: Dies generiert eine eindeutige ID basierend auf einer MAC-Adresse der Netzwerkkarte und einem Timer. Diese IDs sind leicht vorherzusagen (wenn eine gegeben ist, kann ich möglicherweise eine andere erraten) und können auf Ihre Netzwerkkarte zurückgeführt werden. Es wird nicht empfohlen, diese zu erstellen.

  • Version 4: Diese werden aus Zufallszahlen (oder Pseudozufallszahlen) generiert. Wenn Sie nur eine UUID generieren müssen, ist dies wahrscheinlich das, was Sie wollen.

Wenn Sie immer dieselbe UUID aus einem bestimmten Namen generieren müssen, möchten Sie eine Version 3 oder Version 5.

  • Version 3: Dies generiert eine eindeutige ID aus einem MD5-Hash eines Namespace und eines Namens. Wenn Sie Abwärtskompatibilität benötigen (mit einem anderen System, das UUIDs aus Namen generiert), verwenden Sie diese.

  • Version 5: Dies generiert eine eindeutige ID aus einem SHA-1-Hash eines Namespace und eines Namens. Dies ist die bevorzugte Version.

Gabe
quelle
17
Ich würde hinzufügen: Wenn Sie eine reproducibleUUID aus einem bestimmten Namen generieren müssen , möchten Sie eine Version 3 oder Version 5. Wenn Sie diesem Algorithmus dieselbe Eingabe zuführen, wird dieselbe Ausgabe generiert.
Anregen
3
In einer Cloud-Computing-Umgebung (wie AWS oder GAE) scheint die Schwäche von Version 1 in Vergessenheit geraten zu sein. Wenn im Laufe der Zeit wahrscheinlich Tausende verschiedener MAC-Adressen auf den UUID-Generator einer bestimmten Anwendung angewendet werden, wird die Vorhersagbarkeit und / oder Rückverfolgbarkeit beseitigt.
Buffalo Rabor
3
@ user239558 Da das Ziel einer UUID ihre Einzigartigkeit ist, kann UUIDv5 weiterhin bevorzugt werden.
Epikurist
7
Dieser Kommentar, dass Version 1 "nicht empfohlen" wird, ist zu simpel. In vielen Situationen sind diese in der Tat in Ordnung und vorzuziehen. Wenn Sie jedoch Sicherheitsbedenken hinsichtlich des Verlusts einer dieser Informationen aus einer UUID haben, die möglicherweise nicht vertrauenswürdigen Akteuren zur Verfügung gestellt werden: (a) die MAC-Adresse des Computers, der die UUID erstellt, oder (b) das Datum und die Uhrzeit der Erstellung, Vermeiden Sie dann Version 1. Wenn diese beiden Informationen nicht vertraulich sind, ist Version 1 ein hervorragender Weg.
Basil Bourque
9
Was ist mit Version 2 passiert?
Matthew Woo
53

Wenn Sie eine Zufallszahl wünschen, verwenden Sie eine Zufallszahlenbibliothek. Wenn Sie eine eindeutige Kennung mit effektiv 0,00 ... viel mehr Nullen hier ... 001% Kollisionswahrscheinlichkeit wünschen, sollten Sie UUIDv1 verwenden. Siehe Nicks Beitrag für UUIDv3 und v5.

UUIDv1 ist NICHT sicher. Es soll nicht sein. Es soll EINZIGARTIG sein, nicht unvorstellbar. UUIDv1 verwendet den aktuellen Zeitstempel sowie eine Maschinenkennung und einige zufällige Elemente, um eine Zahl zu erstellen, die von diesem Algorithmus nie wieder generiert wird. Dies ist für eine Transaktions-ID geeignet (selbst wenn jeder Millionen von Transaktionen ausführt).

Um ehrlich zu sein, verstehe ich nicht, warum UUIDv4 existiert ... beim Lesen von RFC4122 sieht es so aus, als würde diese Version die Möglichkeit von Kollisionen NICHT ausschließen. Es ist nur ein Zufallsgenerator. Wenn dies zutrifft, haben Sie eine sehr gute Chance, dass zwei Maschinen auf der Welt schließlich dieselbe "UUID" v4 erstellen (zitiert, weil es keinen Mechanismus zur Gewährleistung der U.niversal U.niqueness gibt). In dieser Situation glaube ich nicht, dass der Algorithmus zu einem RFC gehört, der Methoden zum Generieren eindeutiger Werte beschreibt. Es würde in einen RFC über das Erzeugen von Zufälligkeit gehören. Für eine Reihe von Zufallszahlen:

chance_of_collision = 1 - (set_size! / (set_size - tries)!) / (set_size ^ tries)
anregen
quelle
67
Sie werden nicht sehen, dass zwei UUID-Implementierungen der Version 4 kollidieren, es sei denn, Sie generieren ein Jahrhundert lang jede Sekunde eine Milliarde UUIDs und gewinnen einen Münzwurf . Denken Sie daran, set_sizeist 2 ^ 122, was sehr groß ist .
Kevin
8
Der V4-Algorithmus ist nicht seriell, was bedeutet, dass die ersten beiden von v4 generierten UUIDs möglicherweise übereinstimmen. Nur weil es viele Optionen gibt, bedeutet dies nicht, dass Ihnen die eindeutigen Optionen ausgehen müssen, bevor Sie eine Wiederholung generieren. Das kann jederzeit passieren.
Anregen
7
Sie können nicht wirklich rechnen. Wir (als Spezies) erzeugen nicht jede Sekunde 1 Milliarde UUIDs. Wir haben also länger als 100 Jahre bis zur ersten Kollision (im Durchschnitt).
Kevin
31
V4 "könnte" kollidieren, aber die Wahrscheinlichkeit ist außergewöhnlich gering, dass es für die meisten Anwendungsfälle das Risiko wert ist. Betreff: "Zwei Maschinen auf der Welt erstellen schließlich dieselbe 'UUID'v4", na klar, aber dies ist kein Problem, da die meisten Maschinen auf der Welt, die UUIDs verwenden, diese in unterschiedlichen Kontexten verwenden. Ich meine, wenn ich für meine eigene interne App dieselbe UUID generiere wie für Ihre interne App, spielt das keine Rolle. Kollisionen sind nur dann von Bedeutung, wenn sie im selben Kontext auftreten. (
6
Wenn Sie also nicht möchten, dass Ihre Guid sicher ist, verwenden Sie Version 1. Wenn Sie sie sicher benötigen und sich glücklich fühlen (oder sich wirklich nicht unglücklich fühlen), verwenden Sie Version 4.
Vaccano
16

Das ist eine sehr allgemeine Frage. Eine Antwort lautet: "Es hängt davon ab, welche Art von UUID Sie generieren möchten". Aber eine bessere ist folgende: "Bevor ich antworte, können Sie uns sagen, warum Sie Ihren eigenen UUID-Generierungsalgorithmus codieren müssen, anstatt die UUID-Generierungsfunktionalität aufzurufen, die die meisten modernen Betriebssysteme bieten?"

Dadurch , dass ist einfacher und sicherer, und da Sie wahrscheinlich nicht brauchen Ihre eigenen zu generieren, warum die Mühe eine Implementierung Codierung auf? In diesem Fall wird die Antwort unabhängig von Ihrem Betriebssystem, Ihrer Programmiersprache oder Ihrem Framework verwendet. In Windows gibt es beispielsweise CoCreateGuid oder UuidCreate oder einen der verschiedenen Wrapper, die in den zahlreichen verwendeten Frameworks verfügbar sind. Unter Linux gibt es uuid_generate .

Wenn Sie aus irgendeinem Grund unbedingt Ihre eigenen generieren müssen, haben Sie zumindest den gesunden Menschenverstand, sich von der Generierung von v1- und v2-UUIDs fernzuhalten . Es ist schwierig, diese richtig zu machen. Halten Sie sich stattdessen an die UUIDs v3, v4 oder v5.

Update : In einem Kommentar erwähnen Sie, dass Sie Python verwenden, und verlinken darauf . Wenn Sie sich die bereitgestellte Schnittstelle ansehen, ist es für Sie am einfachsten, durch Aufrufen eine v4-UUID (dh eine aus zufälligen Daten erstellte UUID) zu generieren uuid.uuid4().

Wenn Sie über Daten verfügen, die Sie zum Generieren einer UUID benötigen (oder können), können Sie entweder v3 (basierend auf MD5) oder v5 (basierend auf SHA1) verwenden. Das Generieren einer v3- oder v5-UUID ist einfach: Wählen Sie zuerst den UUID-Typ aus, den Sie generieren möchten (Sie sollten wahrscheinlich v5 auswählen), wählen Sie dann den entsprechenden Namespace aus und rufen Sie die Funktion mit den Daten auf, aus denen Sie die UUID generieren möchten. Wenn Sie beispielsweise eine URL hashen, würden Sie Folgendes verwenden NAMESPACE_URL:

uuid.uuid3(uuid.NAMESPACE_URL, 'https://ripple.com')

Bitte beachten Sie, dass sich diese UUID von der v5-UUID für dieselbe URL unterscheidet, die wie folgt generiert wird:

uuid.uuid5(uuid.NAMESPACE_URL, 'https://ripple.com')

Eine nette Eigenschaft von v3- und v5-URLs ist, dass sie zwischen Implementierungen interoperabel sein sollten. Mit anderen Worten, wenn zwei verschiedene Systeme eine Implementierung verwenden, die RFC4122 entspricht, generieren (oder sollten ) beide dieselbe UUID, wenn alle anderen Dinge gleich sind (dh dieselbe UUID der Version mit demselben Namespace und dem gleiche Daten). Diese Eigenschaft kann in einigen Situationen sehr hilfreich sein (insbesondere in inhaltsadressierbaren Speicherszenarien), in Ihrem speziellen Fall jedoch möglicherweise nicht.

Nik Bougalis
quelle
4
Ich würde vermuten, dass OP nicht gefragt hat: Wie kann ich "meinen eigenen UUID-Generierungsalgorithmus codieren, anstatt die UUID-Generierungsfunktionalität aufzurufen, die die meisten modernen Betriebssysteme bieten?"
Anregen
Abgesehen davon denke ich, dass es eine gute Erklärung für UUIDv3 und v5 ist. In meiner Antwort unten erfahren Sie, warum ich denke, dass v1 eine gute Wahl sein kann.
Anregen
Was ist NAMESPACE_URL? Es ist eine Variable, die ich bekommen kann? wovon?
Stackdave
@stackdave NAMESPACE_URList eine UUID, die normalerweise 6ba7b811-9dad-11d1-80b4-00c04fd430c8der Empfehlung auf Seite 30 von RFC-4122 entspricht .
Jamie Ridding
2

Die Postgres-Dokumentation beschreibt die Unterschiede zwischen UUIDs. Ein paar von ihnen:

V3:

uuid_generate_v3(namespace uuid, name text) - Diese Funktion generiert eine UUID der Version 3 im angegebenen Namespace unter Verwendung des angegebenen Eingabenamens.

V4:

uuid_generate_v4 - Diese Funktion generiert eine UUID der Version 4, die vollständig aus Zufallszahlen abgeleitet wird.

Eugen Konkov
quelle