Ein Universally Unique Identifier (UUID) ist eine 128-Bit-Zahl, welche als Identifikator von Informationen in Computersystemen verwendet wird. Der Ausdruck Globally Unique Identifier (GUID) wird ebenfalls benutzt, typischerweise im Zusammenhang mit Microsoft (z. B. Software, Registry).

Bei der Generierung nach den Standardmethoden können UUIDs für praktische Zwecke als global eindeutig angenommen werden. Obwohl die Wahrscheinlichkeit, dass eine UUID dupliziert wird, nicht null ist, ist sie so gering, dass die Wahrscheinlichkeit für eine Kollision zumeist vernachlässigbar ist. Ein Vorteil von UUIDs ist die – im Gegensatz zu den meisten anderen Nummerierungsschemata – Unabhängigkeit von einer zentralen Registrierungsstelle oder Koordinierung zwischen den Parteien.

Daher kann jeder einen UUID erstellen und ihn zur Identifizierung eines Objekts verwenden und dabei mit größtmöglicher Sicherheit davon ausgehen, dass die Kennung keine andere Kennung dupliziert, die bereits erstellt wurde oder in Zukunft zur Identifizierung eines anderen Objekts erstellt wird.

Die Verwendung von UUIDs und GUIDs ist weit verbreitet. Viele Computerplattformen bieten Unterstützung beim Generieren und Parsen ihrer Textdarstellung.

Er wurde von der Open Software Foundation (OSF) als Teil des Distributed Computing Environment (DCE) standardisiert und ist jetzt in RFC 9562 geregelt.

Eine UUID besteht aus einer Zahl mit 16-Bytes (128 Bits), die hexadezimal notiert und in fünf, mit Bindestrichen abgetrennten Gruppen, unterteilt wird.

In seiner Normalform sieht eine UUID beispielsweise so aus:

8be4df61-93ca-11d2-aa0d-00e098032b8c

Zur eindeutigen Kennzeichnung einer UUID hat sich in vielen Implementierungen jedoch etabliert, diese Zeichenkette in geschweiften Klammern anzugeben:

{8be4df61-93ca-11d2-aa0d-00e098032b8c}

Sprachgebrauch

Der Genus der Abkürzungen UUID und GUID ist nicht eindeutig festgelegt. Meist werden sie in ihrer weiblichen Form benutzt („die UUID“, „die GUID“, im Sinne von „UUID-Nummer“), die nach der deutschen Sprachmelodie natürlicher klingt, aber auch die männliche Form kommt gelegentlich vor.apple.com Die UUID (mehrfach)ibm.com Die UUIDlenovo.com Optional können Sie die Universal Unique Identifier (UUID) aktualisieren.

Geschichte und Standardisierung

UUID sind als Teil des Standards ISO/IEC 11578:1996 “Information technology – Open Systems Interconnection – Remote Procedure Call (RPC)” und als separater Standard ISO/IEC 9834-8:2005 dokumentiert. Die IETF hat das auf UUID basierende RFC 4122 veröffentlicht.

Das originale (Version 1) Generierungsschema für UUID war, die UUID-Version mit der MAC-Adresse des Computers, der den UUID generiert, und der Anzahl der 100-Nanosekunden-Intervalle seit Beginn des Gregorianischen Kalenders aneinanderzuhängen. In der Praxis ist der eigentliche Algorithmus komplizierter. Dieses Schema wurde kritisiert, weil es sowohl die Identität des generierenden Computers als auch den Zeitpunkt der Generierung preisgibt.

Mehrere andere Algorithmen zur Generierung wurden entwickelt und flossen in den Standard ein, so ein Schema, welches nur auf Zufallszahlen basiert (Version 4 UUID), und Schemata, in denen der UUID aus einem beliebigen String (z. B. DNS-Eintrag, URL, ISO OID, „X.500 Distinguished Names“, aber auch jeder beliebigen anderen Semantik, sofern ein Basis-UUID dafür definiert wird) über MD5- (Version 3 UUID) oder SHA-1- (Version 5 UUID) Hashwerte hergeleitet wird.

Aufbau RFC 4122 beschreibt den Aufbau eines UUID. Die Namen der einzelnen Felder orientieren sich an der ursprünglichen UUID-Version 1 und sind bei den heute vorwiegend verwendeten zufällig generierten UUIDs nur noch von historischem Interesse.

+ Aufbau einer UUID nach RFC 4122 Offset Feldname Datentyp Beschreibung 0 time_low uint32_t Zeitstempel, niederstwertige 32 Bits 4 time_mid uint16_t Zeitstempel, mittlere 16 Bits 6 time_hi_and_version uint16_t Oberste Bits des Zeitstempels in den unteren 12 Bits des Feldes, die oberen 4 Bits dienen als Versionsbezeichner 8 clock_seq_high_and_reserved uint8_t Oberste 6 Bits der Clocksequenz (die obersten 2 Bits des Feldes sind in der hier beschriebenen UUID-Variante stets 1 0) 9 clock_seq_low uint8_t Untere 8 Bits der Clocksequenz 10 node uint48_t Eindeutige Node-Identifikationsnummer

Das zugehörige Bitfelddiagramm sieht wie folgt aus: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | time_low | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | time_mid |version| time_hi | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |clk_seq_hi_res | clk_seq_low | node (0-1) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | node (2-5) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Die obersten vier Bits im Feld time_hi_and_version geben dabei die sogenannte Version des UUID an. Strenggenommen ist dies keine Version, sondern eine Art UUID-Subtyp. Folgende 5 Versionen sind bisher definiert worden:

+ UUID-Versionen nach RFC 4122 Version Beschreibung 1 ursprünglicher, zeitstempelbasierter UUID 2 DCE Security version 3 namensbasiert, MD5-gehasht 4 zufälliger oder pseudozufälliger UUID 5 namensbasiert, SHA1-gehasht

Darüber hinaus wird die Einführung von weiteren Versionsnummern diskutiert, wie in folgender Tabelle mit Stand im Jahr 2022 dargestellt.

+ Vorschläge zu neuen UUID-Versionen Version Beschreibung 6 zeitstempelbasierend wie Version 1, aber mit anderer Anordnung der Datenfelder 7 zeitstempelbasierend auf der Unixzeit mit zufälliger oder pseudozufälliger Komponente 8 für experimentelle oder herstellerspezifische Anwendungen

Zeitstempelbasierte UUIDs Der Zeitstempel ist ein 60-Bit-Wert, der die seit dem 15. Oktober 1582 (Einführung des heutigen Gregorianischen Kalenders) vergangenen 100-ns-Intervalle zählt. Um die Zeitstempel eindeutig zu halten, falls die Systemzeit einmal zurückgestellt werden muss, gibt es ein Feld Clock sequence, welches in diesem Fall entweder um 1 erhöht wird oder auf einen neuen (pseudo)zufälligen Wert gesetzt werden soll. Die Node-ID soll die MAC-Adresse einer der im System verbauten Netzwerkkarten sein oder ein pseudozufälliger Wert, falls das System keine MAC-Adresse besitzt.

(Pseudo)zufällig generierte UUIDs (Version 4) Hierbei werden sämtliche Bits, die nicht vom UUID-Format auf feste Werte gesetzt werden, durch (pseudo-)zufällige Werte besetzt.

Obwohl die Eindeutigkeit für einen so generierten UUID nicht garantiert ist, ist die Gesamtzahl der zufällig generierbaren UUIDs mit 2122 ≈ 5,3169 × 1036 so groß, dass die Wahrscheinlichkeit der Erzeugung zweier gleicher UUIDs sehr klein ist, sofern die verwendeten Zufallszahlenalgorithmen gleichverteilte Zufallszahlen liefern. Daher können UUIDs beliebig ohne zentrales Kontrollorgan erzeugt und zur Kennzeichnung eingesetzt werden, ohne relevante Gefahr zu laufen, dass derselbe UUID für etwas anderes verwendet wird. Mit UUID markierte Informationen können somit später in einer einzigen Datenbank zusammengeführt werden, ohne Bezeichnerkonflikte auflösen zu müssen.

Namensbasierte UUIDs (Version 3 und 5)

Hierbei wird ausgehend von einem nicht näher bestimmten Namen eine UUID generiert. Namen sind innerhalb eines zugewiesenen Namensraums eindeutige Bezeichner für ein Objekt, eine Ressource oder Ähnliches. Ausgehend von einem UUID für den Namensraum wird aus dem Namen eine UUID generiert, indem eine Bytesequenz aus der Namensraum-UUID und dem Namen selbst gebildet wird und diese Bytesequenz dann mit MD5 oder SHA1 gehasht wird. Der Hash wird dann auf definierte Weise auf die verfügbaren UUID-Bits verteilt.

RFC 4122 enthält beispielhafte Namensraum-UUIDs für die Namensräume DNS, URL, ISO OID und „X.500 Distinguished Names“.

Soll beispielsweise aus dem DNS-Namen www.example.org eine UUID-Version 5 generiert werden, so ist wie folgt vorzugehen:

Namespace-UUID für „DNS“-Namen ist 6ba7b810-9dad-11d1-80b4-00c04fd430c8. An diese Bytefolge wird die Bytefolge für den Namen www.example.org angehängt (Bytes vom Namespace-UUID in fett):0x6b 0xa7 0xb8 0x10 0x9d 0xad 0x11 0xd1 0x80 0xb4 0x00 0xc0 0x4f 0xd4 0x30 0xc8 0x77 0x77 0x77 0x2e 0x65 0x78 0x61 0x6d 0x70 0x6c 0x65 0x2e 0x6f 0x72 0x67. Diese Bytesequenz ist mit SHA1 zu hashen. Das Ergebnis ist folgender SHA1-Hash: 74738ff55367e9589aee98fffdcd187694028007 Die Bits des SHA1-Hashes sind auf die verfügbaren Bits der UUID-Version 5 aufzuteilen. Generierter UUID: 74738ff5-5367-5958-9aee-98fffdcd1876. (Die fett markierten Stellen enthalten feste Bits aus UUID-Variante und -Version.)

Zeitstempelbasierte UUIDs (Version 6)

UUIDv6 zielt darauf ab, die Implementierung der UUID Erstellung zu vereinfachen, indem das Bitlayout von UUIDv1 wiederverwendet wird, jedoch mit Änderungen in der Bitreihenfolge für den Zeitstempel.

Der Zeitstempel zählt in 100 Nanosekunden-Intervallen ab dem 15. Oktober 1582 um 00:00:00.00 UTC und wird auf die Felder time_high, time_mid, und time_low aufgeteilt. Das Feld ver wird immer auf die Versionsnummer (6 bzw. 0110b) gesetzt. Das Feld var wird gesetzt auf 10b gesetzt. Das Feld clock_seq, 14 Bits, enthält die Clocksequenz. Die node-Felder können – je nach Implementierung – entweder Zufallswerte enthalten, oder die MAC-Adresse des erstellenden Computers.

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | time_high | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | time_mid | ver | time_low | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |var| clock_seq | node | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | node | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Zeitstempel + Zufallszahl basierte UUIDs (Version 7)

UUIDs der Version 7 bestehen aus unixts: einem 36 Bit UNIX-Zeitstempel (Big-Endian codiert) subsec_a12 Bits für Sekundenbruchteile ver: 4 Bit Versionsnummer (immer auf dem Wert 7 bzw. 0111b gesetzt) subsec_b: 12 Bits für Sekundenbruchteile var: 2 Bits für die UUID Variante (immer 10b) subsec_seq_node: 62 Zufallsbits

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | unixts | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |unixts | subsec_a | ver | subsec_b | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |var| subsec_seq_node | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | subsec_seq_node | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Durch den Zeitstempel wird eine Sortierung in Datenbanken ermöglicht, während durch die Zufallsbits Kollisionen vermieden werden.

Anwendungsspezifische UUIDs (Version 8)

Eine UUIDv8 besitzt im Feld ver den Wert 8 bzw. 1000b und kann verwendet werden, wenn andere UUID Versionen nach [RFC4122] für eine bestimmte Anwendung nicht geeignet sind. Zudem ist ein 2 Bit großes variant Feld definiert, um verschiedene UUID-Implementierungen innerhalb einer Anwendung unterscheiden zu können.

Es wird empfohlen, dass eine UUIDv8 aus timestamp (Zeitstempel der Erstellung), clock sequence (Zählwert, der sich erhöht, wenn mehrere UUIDs für denselben Zeitstempel erstellt werden), und node Felder (Zufallswerte, MAC-Adresse, Hash-Code etc.) bestehen. Diese Felder können hierbei eine beliebige Länge aufweisen.

Das folgende Schema zeigt auf, wie eine UUIDv8 implementiert sein kann:

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp_32 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp_48 | ver | time_or_seq | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |var| seq_or_node | node |