Les UUID de type 3 et de type 5 ne sont qu'une technique d'insertion d'un hachage en un UUID :
- Type 1 : trucs et astuces MAC address + datetime en 128 bits
- Type 3 Le projet de loi sur l'emploi et l'égalité des chances est en cours d'élaboration. MD5 hash en 128 bits
- Type 4 : trucs et astuces random data en 128 bits
- Type 5 Le projet de loi sur l'emploi et l'égalité des chances est en cours d'élaboration. SHA1 hachage en 128 bits
- Type 6 : idée non officielle pour les UUID séquentiels
Editer : Le type 6 non officiel a maintenant un type officiel rfc
Un hachage SHA1 produit 160 bits (20 octets) ; le résultat du hachage est converti en UUID.
Avec un condensé de 20 octets de SHA1 :
SHA1 Digest: 74738ff5 5367 e958 1aee 98fffdcd1876 94028007
UUID (v5): 74738ff5-5367-5958-9aee-98fffdcd1876
⭡ ⬑first two bits set to 1 and 0, respectively
╰─low nibble is set to 5, to indicate type 5
Qu'est-ce que je hache ?
Vous vous demandez probablement ce que je suis censé hacher. En fait, il s'agit de hacher la concaténation de :
sha1( NamespaceUUID + AnyString ) ;
Vous préfixez votre chaîne de caractères par ce que l'on appelle un espace de noms pour éviter les conflits de noms.
En UUID RFC prédéfinit quatre espaces de noms pour vous :
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}
Ainsi, vous pourriez hacher ensemble :
StackOverflowDnsUUID = sha1(Namespace_DNS + "stackoverflow.com");
StackOverflowUrlUUID = sha1(Namespace_URL + "stackoverflow.com");
Le RFC définit ensuite comment :
- prendre les 160 bits de SHA1
- et le convertir en 128 bits d'un UUID
L'idée de base est de ne prendre que les 128 premiers bits, de mettre un 5
dans le type puis de définir les deux premiers bits de l'enregistrement clock_seq_hi_and_reserved
à 1 et 0, respectivement.
Plus d'exemples
Maintenant que vous disposez d'une fonction qui génère un fichier appelé Nom vous pouvez avoir la fonction (en pseudo-code) :
UUID NameToUUID(UUID NamespaceUUID, String Name)
{
//Note: All code on stackoverflow is public domain - no attribution required.
Byte[] hash = sha1(NamespaceUUID.ToBytes() + Name.ToBytes());
Uuid result;
//Copy first 16-bytes of the hash into our Uuid result
Copy(hash, result, 16);
//set high-nibble to 5 to indicate type 5
result[6] &= 0x0F;
result[6] |= 0x50;
//set upper two bits to "10"
result[8] &= 0x3F;
result[8] |= 0x80;
return result;
}
(Note : l'endianité de votre système peut affecter les indices des octets ci-dessus)
Vous pouvez désormais passer des appels :
uuid = NameToUUID(Namespace_DNS, 'www.stackoverflow.com');
uuid = NameToUUID(Namespace_DNS, 'www.google.com');
uuid = NameToUUID(Namespace_URL, 'http://www.stackoverflow.com');
uuid = NameToUUID(Namespace_URL, 'http://www.google.com/search&q=rfc+4112');
uuid = NameToUUID(Namespace_URL, 'http://stackoverflow.com/questions/5515880/test-vectors-for-uuid-version-5-converting-hash-into-guid-algorithm');
Revenons à votre question
Pour les UUID de la version 3 et de la version 5, les arguments supplémentaires de la ligne de commande namespace et name doivent être fournis. L'espace de noms est soit un UUID sous forme de chaîne de caractères, soit un identifiant pour des UUID d'espaces de noms prédéfinis en interne (actuellement connus sous les noms de "ns:DNS", "ns:URL", "ns:OID" et "ns:X500"). Le nom est une chaîne de longueur arbitraire.
En espace de noms est l'UUID de votre choix. Il peut s'agir d'un des UUID prédéfinis, ou vous pouvez créer le vôtre, par exemple 1 :
UUID Namespace_RectalForeignExtractedObject = '8e884ace-bee4-11e4-8dfc-aa07a5b093db'
Le nom est une chaîne de caractères de longueur arbitraire.
Le nom est simplement le texte que vous souhaitez voir ajouté à l'espace de noms, puis haché et inséré dans un UUID :
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'screwdriver');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'toothbrush');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'broomstick');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'orange');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'axe handle');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'impulse body spray');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'iPod Touch');