In unserer Anwendung erstellen wir XML-Dateien mit einem Attribut, das einen Guid-Wert hat. Dieser Wert musste zwischen den Dateiaktualisierungen konsistent sein. Selbst wenn sich alles andere in der Datei ändert, sollte der Guid-Wert für das Attribut gleich bleiben.
Eine naheliegende Lösung bestand darin, ein statisches Wörterbuch mit dem Dateinamen und den für sie zu verwendenden Guids zu erstellen. Wenn wir dann die Datei generieren, suchen wir im Wörterbuch nach dem Dateinamen und verwenden die entsprechende Anleitung. Dies ist jedoch nicht möglich, da wir möglicherweise auf Hunderte von Dateien skalieren und keine große Liste von Anleitungen führen wollten.
Ein anderer Ansatz bestand darin, die Guid basierend auf dem Pfad der Datei gleich zu machen. Da unsere Dateipfade und die Anwendungsverzeichnisstruktur eindeutig sind, sollte die Guid für diesen Pfad eindeutig sein. Jedes Mal, wenn wir ein Upgrade ausführen, erhält die Datei die gleiche Anleitung basierend auf ihrem Pfad. Ich habe einen coolen Weg gefunden, um solche ' Deterministic Guids ' zu generieren (Danke Elton Stoneman). Es macht im Grunde das:
private Guid GetDeterministicGuid(string input)
{
//use MD5 hash to get a 16-byte hash of the string:
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
byte[] inputBytes = Encoding.Default.GetBytes(input);
byte[] hashBytes = provider.ComputeHash(inputBytes);
//generate a guid from the hash:
Guid hashGuid = new Guid(hashBytes);
return hashGuid;
}
Wenn Sie also eine Zeichenfolge angeben, ist die Guid immer dieselbe.
Gibt es andere Ansätze oder empfohlene Wege, um dies zu tun? Was sind die Vor- oder Nachteile dieser Methode?
Dadurch wird jede Zeichenfolge in eine Guid konvertiert, ohne dass eine externe Assembly importiert werden muss.
Es gibt viel bessere Möglichkeiten, eine eindeutige Guid zu generieren, aber dies ist eine Möglichkeit, einen String-Datenschlüssel konsistent auf einen Guid-Datenschlüssel zu aktualisieren.
quelle
Wie Rob erwähnt, generiert Ihre Methode keine UUID, sondern einen Hash, der wie eine UUID aussieht.
Der RFC 4122 für UUIDs ermöglicht speziell deterministische (namensbasierte) UUIDs - Die Versionen 3 und 5 verwenden md5 bzw. SHA1. Die meisten Leute kennen wahrscheinlich Version 4, die zufällig ist. Wikipedia gibt einen guten Überblick über die Versionen. (Beachten Sie, dass die Verwendung des Wortes "Version" hier einen "Typ" der UUID zu beschreiben scheint - Version 5 ersetzt Version 4 nicht).
Es scheint einige Bibliotheken zum Generieren von UUIDs der Version 3/5 zu geben, darunter das Python- UUID- Modul , boost.uuid (C ++) und OSSP-UUID . (Ich habe keine .net gesucht)
quelle
Sie müssen zwischen Instanzen der Klasse
Guid
und Bezeichnern unterscheiden, die global eindeutig sind. Ein "deterministischer Guid" ist eigentlich ein Hash (wie aus Ihrem Aufruf hervorgehtprovider.ComputeHash
). Hashes haben eine viel höhere Wahrscheinlichkeit für Kollisionen (zwei verschiedene Strings erzeugen zufällig denselben Hash) als Guid, die über erstellt wurdenGuid.NewGuid
.Das Problem bei Ihrem Ansatz ist also, dass Sie mit der Möglichkeit einverstanden sein müssen, dass zwei verschiedene Pfade dieselbe GUID erzeugen. Wenn Sie einen Bezeichner benötigen, der für eine bestimmte Pfadzeichenfolge eindeutig ist, verwenden Sie am einfachsten die Zeichenfolge . Wenn Sie möchten, dass die Zeichenfolge von Ihren Benutzern verdeckt wird, verschlüsseln Sie sie - Sie können ROT13 oder etwas Stärkeres verwenden ...
Der Versuch, etwas, das keine reine GUID ist, in den GUID-Datentyp einzuschleusen, könnte in Zukunft zu Wartungsproblemen führen ...
quelle
MD5 ist schwach. Ich glaube, Sie können mit SHA-1 dasselbe tun und bessere Ergebnisse erzielen.
Übrigens, nur eine persönliche Meinung: Wenn Sie einen MD5-Hash als GUID verkleiden, ist dies keine gute GUID. GUIDs sind von Natur aus nicht deterministisch. Das fühlt sich an wie ein Betrüger. Warum nennst du nicht einfach einen Spaten einen Spaten und sagst, es ist ein String, der als Hash der Eingabe gerendert wird? Sie können dies tun, indem Sie diese Zeile anstelle der neuen Hilfslinie verwenden:
quelle
Guid
?