UUID-Generator
Erzeuge UUIDs einzeln oder fünfzig: zufällige v4 oder zeitlich geordnete v7, die dank ihres Zeitstempels sortierbar sind und als Datenbankschlüssel taugen.
122 Zufallsbits. Verrät nichts über den Entstehungszeitpunkt.
Wird erzeugt…
Was ein UUID ist und warum es ihn gibt
Ein UUID — Universally Unique Identifier, in der Microsoft-Dokumentation GUID genannt — ist ein 128-Bit-Wert, geschrieben als 32 Hexadezimalziffern in der vertrauten Gruppierung 8-4-4-4-12. Sein ganzer Zweck ist es, getrennten Systemen zu erlauben, Bezeichner unabhängig voneinander zu prägen, ganz ohne Absprache, und sich dennoch darauf zu verlassen, dass nichts kollidiert. Genau das unterscheidet ihn von einer Auto-Increment-Spalte: zwei Server, zwei mobile Clients offline im Flugzeug und ein Hintergrundjob können alle im selben Moment Datensätze anlegen, ohne irgendwen um Erlaubnis zu fragen.
Eindeutigkeit ist hier wahrscheinlichkeitsbasiert, nicht garantiert. Version 4 überlässt 122 Bit dem Zufall — ein Raum, der groß genug ist, dass selbst nach Milliarden erzeugter Werte die Wahrscheinlichkeit einer Wiederholung weit unter der liegt, dass eine Festplatte die Daten stillschweigend beschädigt. In der Praxis dürfen Sie ihn als eindeutig behandeln; die Mathematik ist nicht das schwache Glied.
Version 4 gegen Version 7 — die Entscheidung, auf die es ankommt
Version 4 ist von vorn bis hinten zufällig. Sie trägt keinerlei Information: nicht wann sie entstand, nicht von wem, nicht in welcher Reihenfolge. Das ist je nach Einsatzort ihre größte Stärke oder ihr zentraler Mangel.
Version 7, 2024 in RFC 9562 standardisiert, ersetzt die ersten 48 Bit durch einen Unix-Zeitstempel in Millisekunden und füllt den Rest mit Zufall. Weil die Zeit vorne steht und der Wert von links nach rechts gelesen wird, sortiert das Sortieren von v7-Bezeichnern als reiner Text sie zugleich chronologisch.
Das ist kein kosmetischer Unterschied. Datenbanken halten Primärschlüssel in einem sortierten B-Baum-Index. Fügen Sie v7-Schlüssel ein, landet jede neue Zeile am rechten Rand des Baums, direkt neben der vorigen — die beschriebenen Seiten bleiben im Speicher und der Index wächst geordnet. Fügen Sie v4-Schlüssel ein, landet jeder Schreibvorgang an zufälliger Stelle, die Datenbank fasst jedes Mal eine andere Seite an, die Cache-Trefferquote sinkt und der Index fragmentiert. Bei einer großen, stark genutzten Tabelle ist der Unterschied im Einfüge-Durchsatz erheblich — deshalb hat sich v7 für Primärschlüssel so schnell durchgesetzt.
- Wählen Sie v7 für Datenbank-Primärschlüssel, Ereignis- und Log-Bezeichner und alles, was Sie nach Erstellungszeit sortieren oder per Bereichsabfrage suchen wollen.
- Wählen Sie v4, wenn der Bezeichner an unvertrauter Stelle auftaucht und nichts verraten darf — auch nicht, dass ein Datensatz kurz vor einem anderen entstand.
- Beides taugt für eine Correlation-ID, einen Idempotenzschlüssel oder einen Dateinamen, wo die Reihenfolge keine Rolle spielt.
Der Preis ist genau dieses Leck: Ein v7-Bezeichner verrät jedem, der ihn sieht, auf die Millisekunde genau seinen Entstehungszeitpunkt. Bei einer Zeilen-ID ist das meist harmlos und oft nützlich. Bei einem Passwort-Zurücksetzen-Token oder einem öffentlichen Freigabelink ist es eine Information, die Sie nicht veröffentlichen wollten — und solche Dinge sollten überhaupt keine UUIDs sein, sondern Zufallstoken aus einem eigenen Geheimnisgenerator.
Reihenfolge innerhalb derselben Millisekunde
Eine Feinheit, über die viele v7-Implementierungen stolpern: Moderne Hardware erzeugt weit mehr als einen Bezeichner pro Millisekunde. Teilen sich zwei Werte einen Zeitstempel, entscheiden die folgenden Zufallsbits über ihre Reihenfolge — also der Zufall. Erzeugen Sie fünfzig in einer engen Schleife, erhalten Sie fünfzig nur ungefähr geordnete Werte und verlieren genau die Eigenschaft, für die Sie v7 gewählt haben.
RFC 9562 begegnet dem mit einem monotonen Zähler, und dieses Werkzeug setzt ihn um: Die 12 Bit direkt nach dem Zeitstempel zählen innerhalb einer Millisekunde aufwärts, sodass ein Stapel streng statt nur ungefähr aufsteigend ist. Läuft der Zähler voll — mehr als 4096 Werte in derselben Millisekunde —, borgt sich der Generator die nächste Millisekunde, statt überzulaufen und einen Wert auszugeben, der vor seinem Vorgänger sortiert. Eine rückwärts laufende Uhr, wie sie bei NTP-Korrekturen vorkommt, behandelt er genauso.
Ein v7-Wert von links nach rechts gelesen, am Beispiel 0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b:
- 0190a1b2-c3d4 — der 48-Bit-Unix-Zeitstempel in Millisekunden. Weil er vorne steht, ist Textreihenfolge gleich Zeitreihenfolge.
- 7 — die Versionsziffer, die diesen Wert zu einem v7 statt einem v4 macht.
- e5f — der 12-Bit-Monotoniezähler, der innerhalb einer Millisekunde hochzählt.
- 8 — die Variantenbits, von RFC 9562 für jeden modernen UUID festgelegt (immer 8, 9, a oder b).
- a9b-0c1d2e3f4a5b — die verbleibenden 62 Bit, rein zufällig.
UUIDs speichern und verwenden
Die kanonische Form ist kleingeschrieben mit Bindestrichen, und RFC 9562 verlangt von Generatoren genau das — weshalb dieses Werkzeug keine Formatoptionen anbietet. Andere Schreibweisen begegnen Ihnen trotzdem: groß und in geschweiften Klammern im Microsoft-Umfeld, und ohne Bindestriche dort, wo jemand eine kürzere Spalte wollte. Es sind dieselben 128 Bit, und Vergleiche sollten die Groß- und Kleinschreibung ignorieren.
Wirklich ins Gewicht fällt die Speicherung. Ein UUID ist 16 Byte groß, seine Textform aber 36 Zeichen — als Zeichenkette gespeichert mehr als verdoppelt er also den Platz in der Zeile und, wichtiger noch, in jedem Index, der ihn enthält. Nutzen Sie einen nativen Typ, wo es einen gibt:
uuid -- PostgreSQL: nativer 16-Byte-Typ BINARY(16) -- MySQL: kompakt; CHAR(36) verschwendet 20 Byte/Zeile uniqueidentifier -- SQL Server crypto.randomUUID() // JavaScript: nur v4, braucht sicheren Kontext uuid.uuid4() / uuid7() # Python: v4 in der Standardbibliothek; v7 per Bibliothek
Eine letzte Warnung: Ein UUID identifiziert, er autorisiert nicht. Weil man ihn nicht erraten kann, ist es verlockend, eine nicht verlinkte URL mit einem UUID darin als privat zu betrachten. Aber Bezeichner sickern durch — über Logs, den Browserverlauf, Referrer-Header und Screenshots. Alles, was wirklich Schutz braucht, braucht deshalb weiterhin eine echte Rechteprüfung dahinter.
Woran Sie erkennen, ob ein UUID ein v4 oder ein v7 ist
Meist bekommt man einen Bezeichner ohne jeden Hinweis darauf, woher er stammt, und man braucht auch keinen: Die Version steht im Wert selbst. Beide sind 32 hexadezimale Ziffern in derselben Gruppierung 8-4-4-4-12, der Unterschied liegt also nicht in der Form — er liegt in zwei einzelnen Ziffern an festen Stellen, und alles Weitere folgt daraus.
- Die erste Ziffer der dritten Gruppe ist die Versionsziffer. Eine 4 dort bedeutet Version 4, eine 7 bedeutet Version 7, und kein anderer Teil des Werts redet dabei mit.
- Die erste Ziffer der vierten Gruppe trägt die Variantenbits und ist in beiden Versionen 8, 9, a oder b — sie verrät Ihnen also nie, welche der beiden Sie in der Hand halten. Was sie verrät, ist, dass der Wert überhaupt dem RFC 9562 folgt; alles andere an dieser Stelle ist ein älteres Layout oder gar kein UUID.
- Ist die Versionsziffer eine 7, dann sind die ersten zwölf Ziffern die Erzeugungszeit: eine 48-Bit-Zählung der Millisekunden seit dem Anfang von 1970, hexadezimal geschrieben.
- Ist sie eine 4, gibt es nichts weiter zu lesen. Ein v4 kodiert weder Zeit noch Maschine noch Reihenfolge — genau die Eigenschaft, wegen der man ihn wählt.
Nehmen Sie den Wert, den der Abschnitt oben aufschlüsselt, 0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b. Seine dritte Gruppe beginnt mit einer 7, es ist also ein Version 7, und seine ersten zwölf Ziffern lauten 0190a1b2c3d4 — rechnen Sie diese Hexadezimalzahl ins Dezimale um, geben Sie sie dem Unix-Zeitstempel-Konverter, und Sie erhalten einen Nachmittag im Juli 2024. Daneben beginnt 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d seine dritte Gruppe mit einer 4, und seine eigenen ersten zwölf Ziffern sind Zufallsdaten, die zu nichts dekodieren. In genau einem Punkt stimmen die beiden überein: Beide beginnen ihre vierte Gruppe mit einer der vier Ziffern, die die Variantenbits zulassen.
Ist v7 so kollisionssicher wie v4?
Eine berechtigte Frage, denn v7 enthält tatsächlich weniger Zufall. Version 4 gibt 122 ihrer 128 Bit an Zufallsdaten. Version 7 gibt 48 an den Zeitstempel und hier weitere 12 an den Monotoniezähler, sodass 62 Zufallsbits bleiben — etwas mehr als die Hälfte. Als nackte Zahl gelesen sieht das nach einem ernsten Rückschritt aus.
- Innerhalb eines Stapels aus diesem Werkzeug ist eine Wiederholung nicht unwahrscheinlich, sondern unmöglich. Werte, die sich eine Millisekunde teilen, bekommen verschiedene Zählerstände, und Werte, die sich keine teilen, tragen verschiedene Zeitstempel — es kann also keine zwei gleichen geben. Das ist Arithmetik, nicht Wahrscheinlichkeit.
- Zwischen zwei Maschinen, die im selben Augenblick erzeugen, sind die Chancen schlimmstenfalls das Geburtstagsproblem über 62 Bit, das ungefähr bei der Wurzel des Raums ins Gleichgewicht kippt: bei rund zwei Milliarden Werten, und zwar alle in derselben einen Millisekunde.
- Zwischen verschiedenen Millisekunden ist eine v7-Kollision nicht bloß unwahrscheinlich, sondern unmöglich, weil sich schon die führenden Ziffern unterscheiden.
Der ehrliche Vergleich lautet also nicht 122 Bit gegen 62. Er lautet: eine Lotterie, die das ganze Leben des Systems hindurch immer wieder gezogen wird, gegen eine eigene, weit kleinere Lotterie, die innerhalb jeder Millisekunde stattfindet und weggeworfen wird, sobald die Millisekunde endet. Die zweite Anordnung ist die stärkere, und der Grund, v4 vorzuziehen, bleibt der, den der Vergleichsabschnitt nennt — nicht Kollisionen, sondern dass ein v7 laut ausspricht, wann er entstanden ist.
Eine bestehende Tabelle von v4 auf v7 umstellen
Die Frage, die auf die Entscheidung für v7 folgt, ist, was mit den Zeilen geschehen soll, die schon in der Tabelle stehen — und das Beruhigende ist, dass sich an der Spalte überhaupt nichts ändern muss. Beide Versionen sind dieselben 128 Bit in derselben 36-Zeichen-Textform, eine uuid-Spalte in PostgreSQL, ein BINARY(16) oder ein CHAR(36) hält eine Mischung also, ohne es zu merken. Sie erzeugen ab jetzt v7 für neue Zeilen und hören damit auf; es gibt keinen Migrationsschritt und kein Nachfüllen.
- Was sofort da ist: Jede ab jetzt eingefügte Zeile trägt einen führenden Zeitstempel, neue Schlüssel landen also nebeneinander an einem Ende des Index statt verstreut über ihn. Dieser Gewinn betrifft, wohin neue Schreibvorgänge gehen, und er ist ab der ersten Einfügung da.
- Was nie kommt: Die Zeilen, die schon da sind, bleiben für immer ungeordnet. Nichts kann eine Erzeugungszeit in einen Wert legen, der nie eine bekommen hat, und jeden Bezeichner neu auszustellen hieße, jeden Fremdschlüssel neu zu schreiben, der auf ihn zeigt — weit mehr Arbeit als ein Generatorwechsel, und für einen Index allein lohnt sie sich selten.
- Worauf zu achten ist: Das Sortieren der Spalte bedeutet nicht mehr eine Sache. Eine Zählung von Millisekunden ist für ein 48-Bit-Feld eine kleine Zahl, die v7-Schlüssel sammeln sich also in einem schmalen Band am unteren Ende des Bereichs, während die v4-Schlüssel über den ganzen Bereich verteilt sind und gelegentlich einer von ihnen mitten hineinfällt.
Dieser letzte Punkt ist der, der beißt: Eine Abfrage, die nach dem Schlüssel sortiert, sieht auf neuen Daten richtig aus und meldet die alten stillschweigend falsch. Wenn Sie eine Reihenfolge über die ganze Tabelle brauchen, fügen Sie eine Spalte mit der Erzeugungszeit hinzu und sortieren Sie danach — dann darf der Bezeichner wieder ein Bezeichner sein. Immerhin bleibt die Mischung lesbar, solange das dauert: Die Versionsziffer steht in jedem Wert, eine Abfrage kann die beiden Epochen also im Notfall auch ohne zweite Spalte auseinanderhalten.
Häufig gestellte Fragen
- Sollte ich v4 oder v7 verwenden?
- Nehmen Sie v7 für Primärschlüssel und alles, was Sie nach Erstellungszeit sortieren: Der führende Zeitstempel hält Einfügungen am Ende des Index beisammen, statt sie darüber zu verstreuen. Nehmen Sie v4, wenn der Bezeichner überhaupt nichts verraten darf, auch nicht seinen Entstehungszeitpunkt.
- Können zwei UUIDs jemals gleich sein?
- Möglich, aber verschwindend unwahrscheinlich. Version 4 hat 122 Zufallsbits, sodass selbst nach Milliarden erzeugter Werte die Kollisionswahrscheinlichkeit weit unter der liegt, dass der Speicher sie stillschweigend beschädigt.
- Was ist aus den Versionen 1, 3 und 5 geworden?
- Version 1 kodiert einen Zeitstempel und die MAC-Adresse der Maschine, verrät also die Hardware-Identität und lässt sich im Browser ohnehin nicht erzeugen. Die Versionen 3 und 5 leiten einen UUID deterministisch aus einem Namensraum und einem Namen ab, per MD5 oder SHA-1 — nützlich, wenn dieselbe Eingabe immer denselben Bezeichner ergeben muss, aber eine andere Aufgabe als einen neuen zu erzeugen.
- Ist ein UUID sicher genug als geheimes Token?
- Ein v4-UUID ist nicht erratbar, ein v7 verrät jedoch offen seine Entstehungszeit, und keiner von beiden ist als Zugangsnachweis gedacht. Für Passwort-Zurücksetzungen, Sitzungstoken oder Freigabelinks erzeugen Sie ein eigenes Zufallsgeheimnis und prüfen die Rechte serverseitig, statt sich darauf zu verlassen, dass der Bezeichner schwer zu erraten ist.
- Warum ist mein v7-Stapel in anderen Werkzeugen nicht perfekt sortiert?
- Weil viele Implementierungen den monotonen Zähler auslassen. Teilen sich mehrere Werte eine Millisekunde, entscheiden die folgenden Zufallsbits über ihre Reihenfolge. Dieses Werkzeug setzt den Zähler aus RFC 9562 um, ein hier erzeugter Stapel ist also streng aufsteigend.
- Wie sollte ich einen UUID in einer Datenbank speichern?
- In einem nativen 16-Byte-Typ, wo es einen gibt — uuid in PostgreSQL, uniqueidentifier im SQL Server, BINARY(16) in MySQL. Die 36 Zeichen lange Textform stattdessen zu speichern, verdoppelt den Platzbedarf in der Zeile und in jedem Index mit dieser Spalte mehr als.
- Werden sie auf Ihren Servern erzeugt?
- Nein. Sie entstehen in Ihrem Browser mit crypto.getRandomValues, der kryptografischen Zufallsquelle der Plattform — derselben, die crypto.randomUUID nutzt. Kein Wert wird irgendwohin gesendet, und ein Neuladen der Seite erzeugt einen völlig frischen Satz.
- Kann ich erkennen, wann ein v7-UUID erzeugt wurde?
- Ja, und mehr als den Wert brauchen Sie dafür nicht. Seine ersten zwölf hexadezimalen Ziffern sind eine Zählung der Millisekunden seit dem Anfang von 1970: rechnen Sie sie ins Dezimale um und geben Sie das Ergebnis dem Unix-Zeitstempel-Konverter. Ein v4 hat kein solches Feld, dieselben zwölf Ziffern sind dort also zufällig und dekodieren zu nichts.
- Hat v7 weniger Zufallsbits als v4?
- Ja — hier 62 gegen die 122 von v4, weil der Zeitstempel und der Zähler den Platz einnehmen. Eine Kollision wird dadurch in der Praxis nicht wahrscheinlicher: Zwei v7-Werte können nur kollidieren, wenn sie in derselben Millisekunde entstanden sind, diese 62 Bit werden also innerhalb einer Millisekunde ausgegeben statt über das ganze Leben des Systems — und innerhalb eines Stapels aus diesem Werkzeug macht der Zähler eine Wiederholung unmöglich statt bloß unwahrscheinlich.
- Können v4- und v7-UUIDs in derselben Spalte stehen?
- Ja. Es sind dieselben 128 Bit in derselben Textform, am Schema ändert sich also nichts und eine Migration gibt es nicht — Sie erzeugen ab jetzt v7 und lassen die alten Zeilen in Ruhe. Achten müssen Sie nur auf das Sortieren: Die neuen Zeilen stehen untereinander in Erzeugungsreihenfolge, die alten zufälligen sind aber um sie herum verstreut, eine Sortierung nach dem Schlüssel ist für die Tabelle als Ganzes also keine Zeitreihenfolge.
- Was sind die UUID-Versionen 6 und 8?
- RFC 9562 definiert beide neben v7. Version 6 ist Version 1 mit umgestellten Zeitstempelfeldern, damit der Wert chronologisch sortiert; sie ist für Systeme gedacht, die bereits auf v1 festgelegt sind — alles andere soll laut RFC v7 nehmen. Version 8 ist ein bewusst offener Platz für eigene Layouts, in dem nur die Versions- und Variantenbits festliegen und die übrigen 122 Ihnen gehören. Dieses Werkzeug erzeugt keine von beiden.
Verwandte Werkzeuge
- Token-Generator
Erzeugt sichere Schlüssel, Geheimnisse und Passphrasen.
- Mockdaten-Generator
Testdaten mit Seed, deren Prüfziffern und IBANs wirklich stimmen.
- QR-Code-Generator
Jede Entscheidung der Kodierung sichtbar: Modus, Version, Stufe, Maske.