Name und Namespace können verwendet werden, um eine Hierarchie von (sehr wahrscheinlich) eindeutigen UUIDs zu erstellen.
Grob gesagt wird eine UUID vom Typ 3 oder Typ 5 generiert, indem eine Namespace-ID mit einem Namen zusammengefügt wird. UUIDs vom Typ 3 verwenden MD5 und UUIDs vom Typ 5 verwenden SHA1. Es sind nur 128 Bit verfügbar und 5 Bit werden verwendet, um den Typ anzugeben, sodass nicht alle Hash-Bits in die UUID gelangen. (Auch MD5 gilt als kryptografisch defekt, und SHA1 befindet sich in den letzten Zügen. Verwenden Sie dies also nicht, um Daten zu überprüfen, die "sehr sicher" sein müssen.) Das heißt, es gibt Ihnen eine Möglichkeit, eine wiederholbare / überprüfbare "Hash" -Funktion zu erstellen, die einen möglicherweise hierarchischen Namen einem wahrscheinlich eindeutigen 128-Bit-Wert zuordnet, der möglicherweise wie ein hierarchischer Hash oder MAC wirkt.
Angenommen, Sie haben einen (Schlüssel-, Wert-) Speicher, der jedoch nur einen Namespace unterstützt. Mit UUIDs vom Typ 3 oder 5 können Sie eine große Anzahl unterschiedlicher logischer Namespaces generieren. Erstellen Sie zunächst eine Root-UUID für jeden Namespace. Dies kann eine UUID vom Typ 1 (Host + Zeitstempel) oder vom Typ 4 (zufällig) sein, solange Sie sie irgendwo aufbewahren. Alternativ können Sie eine zufällige UUID für Ihren Stamm erstellen (oder die null
UUID: 00000000-0000-0000-0000-000000000000
als Stamm verwenden) und dann mit " uuid -v5 $ROOTUUID $NAMESPACENAME
" eine reproduzierbare UUID für jeden Namespace erstellen . Jetzt können Sie eindeutige UUIDs für Schlüssel in einem Namespace mit "uuid -v5 $NAMESPACEUUID $KEY
Diese UUIDs können mit hoher Wahrscheinlichkeit zur Vermeidung von Kollisionen in einen einzelnen Schlüsselwertspeicher geworfen werden. Dieser Vorgang kann rekursiv wiederholt werden, so dass beispielsweise der mit einem UUID-Schlüssel verknüpfte "Wert" wiederum eine Art logischen "Namespace darstellt "Wie ein Bucket, Container oder Verzeichnis kann seine UUID wiederum verwendet werden, um hierarchischere UUIDs zu generieren.
Die generierte UUID vom Typ 3 oder Typ 5 enthält einen (Teil-) Hash der Namespace-ID und des Namens innerhalb des Namespace (Schlüssel). Es enthält nicht mehr die Namespace-UUID als ein Nachrichten-MAC den Inhalt der Nachricht, aus der es codiert ist. Der Name ist aus Sicht des UUID-Algorithmus eine "beliebige" (Oktett-) Zeichenfolge. Die Bedeutung hängt jedoch von Ihrer Anwendung ab. Dies kann ein Dateiname in einem logischen Verzeichnis, eine Objekt-ID in einem Objektspeicher usw. sein.
Während dies für eine mäßig große Anzahl von Namespaces und Schlüsseln gut funktioniert, geht ihm schließlich der Dampf aus, wenn Sie eine sehr große Anzahl von Schlüsseln anstreben, die mit sehr hoher Wahrscheinlichkeit eindeutig sind. Der Wikipedia-Eintrag für das Geburtstagsproblem (auch bekannt als Geburtstagsparadoxon) enthält eine Tabelle, in der die Wahrscheinlichkeiten mindestens einer Kollision für verschiedene Anzahlen von Schlüsseln und Tabellengrößen angegeben sind. Für 128-Bit hat das Hashing von 26 Milliarden Schlüsseln auf diese Weise eine Kollisionswahrscheinlichkeit von p=10^-18
(vernachlässigbar), aber 26 Billionen Schlüssel, erhöht die Wahrscheinlichkeit von mindestens einer Kollision auf p=10^-12
(eins zu einer Billion), und das Hashing von 26*10^15
Schlüsseln erhöht die Wahrscheinlichkeit von mindestens eine Kollision mitp=10^-6
(einer von einer Million). Wenn Sie 5 Bits anpassen, die den UUID-Typ codieren, läuft er etwas schneller ab, sodass eine Billion Schlüssel eine Wahrscheinlichkeit von 1 zu 1 Billion für eine einzelne Kollision haben.
Die Wahrscheinlichkeitstabelle finden Sie unter http://en.wikipedia.org/wiki/Birthday_problem#Probability_table .
Weitere Informationen zu UUID-Codierungen finden Sie unter http://www.ietf.org/rfc/rfc4122.txt .
UUIDs vom Typ 3 und Typ 5 sind nur eine Technik zum Einfügen eines Hashs in eine UUID.
Ein SHA1-Hash gibt 160 Bit (20 Bytes) aus; Das Ergebnis des Hashs wird in eine UUID konvertiert.
Mit dem 20-Byte-Hash von SHA1:
(Beachten Sie, dass die ersten beiden Bits von '9' bereits 1 bzw. 0 sind, sodass dies keine Auswirkung hat.)
Was habe ich Hash?
Sie fragen sich wahrscheinlich, was ich hacken soll. Grundsätzlich haben Sie die Verkettung von:
Sie stellen Ihrer Zeichenfolge einen sogenannten Namespace voran , um Namenskonflikte zu vermeiden.
Der UUID-RFC definiert vier Namespaces für Sie vor:
NameSpace_DNS
: {6ba7b810-9dad-11d1-80b4-00c04fd430c8}NameSpace_URL
: {6ba7b811-9dad-11d1-80b4-00c04fd430c8}NameSpace_OID
: {6ba7b812-9dad-11d1-80b4-00c04fd430c8}NameSpace_X500
: {6ba7b814-9dad-11d1-80b4-00c04fd430c8}Sie könnten also zusammen hashen:
Der RFC definiert dann, wie:
Der grundlegende Kern ist es , nur die ersten 128 Bits zu nehmen, material a
5
in der Art aufnehmen, und anschließend die ersten beiden Bits des eingestelltenclock_seq_hi_and_reserved
Abschnitts auf 1 bzw. 0 ist.Mehr Beispiele
Nachdem Sie nun eine Funktion haben, die einen sogenannten Namen generiert , können Sie die Funktion (im Pseudocode) haben:
(Beachten Sie, dass die Endianität Ihres Systems die Indizes der oben genannten Bytes beeinflussen kann.)
Sie können Anrufe haben:
Nun zurück zu Ihrer Frage
Der Namespace ist eine beliebige UUID. Es kann eines der vordefinierten sein, oder Sie können Ihr eigenes erstellen, z.
Der Name ist nur der Text, den Sie an den Namespace anhängen, dann hashen und in eine UUID einfügen möchten:
quelle
Namespace_RectalForeignExtractedObject
würde ich.Ein Name ist nichts anderes als ein Bezeichner, der in einem Namespace eindeutig ist. Das Problem ist, dass Namespaces oft recht klein sind und die Namen in einem oft mit den Namen in anderen kollidieren. Zum Beispiel ist das Autokennzeichen (Name) meines Autos im DMV-Namespace meines Bundesstaates eindeutig, aber wahrscheinlich nicht weltweit eindeutig. DMVs anderer Bundesstaaten haben möglicherweise denselben Namen in ihren eigenen Namespaces verwendet. Heck, jemand anderes kann eine Telefonnummer (Name) haben, die auch übereinstimmt, weil das noch ein anderer Namespace ist, etc.
UUIDs können als Bewohner eines einzelnen Namespace angesehen werden, der so groß ist, dass er für alles einen eindeutigen Namen liefern kann . das ist was "universell" bedeutet. Aber wie ordnet man vorhandene Namen in anderen Namespaces einer UUID zu?
Eine naheliegende Lösung besteht darin, für jedes Element eine UUID (V1 oder V4) zu generieren, um die alten Namen in ihren disjunkten Namespaces zu ersetzen. Der Nachteil ist, dass sie viel größer sind. Sie müssen alle neuen Namen an alle weitergeben, die eine Kopie Ihres Datensatzes haben, alle Ihre APIs aktualisieren usw. Wahrscheinlich können Sie die alten Namen nicht vollständig entfernen Wie auch immer, was bedeutet, dass jetzt jeder Gegenstand zwei Namen hat. Hast du es also besser oder schlechter gemacht?
Hier kommt V3 / V5 ins Spiel. Die UUIDs sehen genauso zufällig aus wie V4, sind aber tatsächlich deterministisch. Jeder, der die richtige UUID für einen Namespace hat, kann dann unabhängig dieselbe UUID für einen bestimmten Namen in diesem Namespace generieren. Sie müssen sie überhaupt nicht veröffentlichen oder vorab generieren, da jeder sie bei Bedarf im laufenden Betrieb erstellen kann!
DNS-Namen und URLs sind sehr häufig verwendete Namespaces, daher wurden für diese Standard-UUIDs veröffentlicht. ASN.1-OIDs und X.500-Namen sind nicht so häufig, aber Standard-Gremien lieben sie. Deshalb haben sie auch Standard-Namespace-UUIDs für sie veröffentlicht.
Für alle anderen Namespaces müssen Sie Ihre eigene Namespace-UUID (V1 oder V4) generieren und an alle weitergeben, die sie benötigen. Wenn Sie mehrere Namespaces haben, ist es eindeutig nicht ideal, die UUID für jeden zu veröffentlichen.
Hier kommt die Hierarchie ins Spiel: Sie erstellen eine "Basis" -UUID (von welchem Typ auch immer) und verwenden diese dann als Namespace für die Benennung Ihrer anderen Namespaces! Auf diese Weise müssen Sie nur die Basis-UUID veröffentlichen (oder eine offensichtliche verwenden), und jeder kann den Rest berechnen.
Bleiben wir zum Beispiel, wir wollten einige UUIDs für StackOverflow erstellen. Das hat einen offensichtlichen Namen innerhalb des DNS-Namespace, daher ist die Basis offensichtlich:
StackOverflow selbst verfügt über separate Namespaces für Benutzer, Fragen, Antworten, Kommentare usw., aber diese sind auch ziemlich offensichtlich:
Diese spezielle Frage lautet # 10867405, daher lautet die UUID:
Beachten Sie, dass dieser Prozess nichts Zufälliges enthält, sodass jeder, der der gleichen Logik folgt, die gleiche Antwort erhält. Der UUID-Namespace ist jedoch so umfangreich, dass er (angesichts der Sicherheit eines kryptografischen 122-Bit-Hashs) niemals mit einem kollidiert UUID, die aus einem anderen Namespace / Name-Paar generiert wurde.
quelle