12. Aug 2024
Lesedauer 4 Min.
Die neue GUID
Neu in .NET 9
IDs mit Zeitstempel.

Man will es kaum glauben, aber selbst eine so integrale Klasse wie die Guid-Klasse wird mit .NET 9 ein Update erhalten. Doch warum greift Microsoft hier ein, und worin besteht das Update? Es ist also an der Zeit, sich mit der Klasse Guid etwas näher auseinanderzusetzen. Historisch gesehen handelt es sich um eine sehr alte Klasse, die seit eh und je Teil des .NET-Ökosystems ist. Die Guid-Klasse kommt immer dann zum Einsatz, wenn man eine eindeutige ID erzeugen möchte; insbesondere bei der Arbeit mit Datenbanken oder verteilten Systemen sind GUIDs sehr beliebt. Eine Besonderheit von GUIDs besteht darin, dass die ID vom Client-System errechnet werden kann und somit nicht im Backend oder im Datenbanksystem erzeugt werden muss.
Wie funktioniert eine GUID?
Die Grundform einer GUID erzeugt der Aufruf der Factory-Methode NewGuid, siehe Bild 1. Ergebnis des Aufrufs ist eine kryptische ID, wie beispielsweise d9d31adb-9d2b-4965-a4be-46e37f5fdb13. Was tut .NET eigentlich, um diese ID zu generieren? Ein Blick auf GitHub [1] erlaubt die Sicht nach „innen“. Tatsächlich besteht eine GUID lediglich aus einigen Feldern: acht Felder sind vom Typ byte, zwei Felder vom Typ short und eines vom Typ int. Das ergibt rein aus der Addition der Feldbreiten (8*8 + 2*16 + 1*32) eine Größe/Länge von 128 Bit, und dies ist auch die eigentliche Größe einer GUID.
Eine einfache GUID erzeugen (Bild 1)
Autor
Den Vergleich zweier GUIDs erledigt die Methode EqualsCore, wie in Bild 2 zu sehen. Darin werden einfach alle Felder miteinander verglichen, und zwar mit einer optimierten Variante: Es werden die jeweiligen Pointer ermittelt, um anschließend mit vier 32-Bit-Vergleichen auf Inhaltsgleichheit zu prüfen.

Der Vergleich von zwei GUIDs erfolgt mit der Methode EqualsCore (Bild 2)
Autor
Die Methode NewGuid hat Microsoft in zwei Varianten implementiert: eine für Windows und eine für Linux, erkennbar an den Namen der jeweiligen .cs-Dateien.Im Fall von Windows wird auf eine Systemfunktion zurückgegriffen, die Bild 3 zeigt, im Fall von Linux auf eine Funktion vom .NET-Team, siehe Bild 4. In beiden Fällen wird eine neue GUID auf dem Stack allokiert und anschließend an die jeweilige Systemfunktion übergeben, damit diese die Bits und Bytes korrekt auffüllt.

Die NewGuid-Methode für Windows nutzt die Funktion CoCreateGuid (Bild 3)
Autor

NewGuid für Linux: Random Bytes (Bild 4)
Autor
Unterschiedliche Versionen
Eine GUID ist Microsofts Implementierung des UUID-Standards [2]. Interessant dabei: Der Standard sieht unterschiedliche Versionen eines Universally Unique Identifiers vor. Allen gemeinsam ist, dass eine UUID 128 Bit hat, aber wie dieser Inhalt generiert wird, unterscheidet sich je nach verwendeter Version. Wikipedia [3] verweist dabei auf den Standard RFC 4122, der fünf Versionen kennt, siehe Bild 5. Hinzu kommen Vorschläge für weitere Varianten (Bild 6), die jedoch noch nicht verabschiedet wurden [4].
Fünf Varianten, um eine UUID zu erzeugen (Bild 5)
Autor

Vorschläge neuer UUID-Versionen (Bild 6)
Autor
Tatsache ist, dass Microsoft bislang immer noch GUIDs nach Version 4 erzeugt – also eine zufällige ID. Dies ist auch in der Linux-Variante sehr gut ersichtlich, die unter der Haube die Funktion minipal_get_cryptographically_secure_random_bytes aufruft, die lediglich zufällige Zahlen generiert.
Was ist denn nun neu?
Erstmals mit .NET 9 wird die Version 7 des UUID-Standards unterstützt. Damit kann eine GUID mit einem Zeitstempel kombiniert werden. GUIDs, die nach Version 4 erzeugt werden, sind rein zufällig, eine Sortierung hat folglich keinen Sinn. Das ändert sich mit Version 7. Damit sind die GUIDs zwar weiterhin zufällig, dank des Zeitstempels lassen sie sich aber sinnvoll sortieren..NET 9 enthält die neue Factory-Methode CreateVersion7, die eine neue ID mit Zeitstempel generiert. In Bild 7 sehen Sie, dass alle ausgegebenen IDs ein ähnliches „Präfix“ teilen, da sie direkt hintereinander erzeugt wurden, der Zeitstempel mithin annähernd gleich ist. Das Sortieren nach der Zeit des Erzeugens der GUID ist so ganz einfach.
CreateVersion7 erzeugt GUIDs mit Zeitstempel (Bild 7)
Autor
Ein Blick in die Implementierung der neuen Methode, siehe Bild 8, zeigt, dass Microsoft die Aufgabe sehr trivial gelöst hat: Durch Aufruf der NewGuid-Methode wird eine normale ID erzeugt, wobei die ersten 64 Bit dann mit dem Zeitstempel und der Versionsmaske versehen werden.

Die neue Methode zum Erzeugen von GUIDs nach Version 7 des UUID-Standards (Bild 8)
Autor
Fazit
Die Klasse System.Guid kennt vermutlich jeder .NET-Entwickler. Wie die Klasse zu ihren Ergebnissen kommt, haben Sie hier erfahren. Mit .NET 9 gibt es nun eine neue Variante, die die Zeit, zu der eine GUID erzeugt wurde, in der ID festhält. Diese Variante zu nutzen ist bei neuen Projekten durchaus eine Überlegung wert.Fussnoten
- System.Guid.cs auf GitHub, http://www.dotnetpro.de/SL2409NETirol1
- UUID-Standard, http://www.ietf.org/rfc/rfc4122.txt
- UUID bei Wikipedia, http://www.dotnetpro.de/SL2409NETirol3
- Neue UUID-Formate, http://www.dotnetpro.de/SL2409NETirol4