Gli UUID di tipo 3 e 5 sono solo una tecnica per inserire un hash in un UUID.
- Tipo 1: inserisce l'indirizzo MAC + datetime in 128 bit
- Tipo 3 : inserisce un hash MD5 in 128 bit
- Tipo 4: inserisce dati casuali in 128 bit
- Tipo 5 : inserisce un hash SHA1 in 128 bit
- Tipo 6: idea non ufficiale per UUID sequenziali
Un hash SHA1 emette 160 bit (20 byte); il risultato dell'hash viene convertito in un UUID.
Con l'hash a 20 byte da SHA1:
SHA1 Digest: 74738ff5 5367 e958 9aee 98fffdcd1876 94028007
UUID (v5): 74738ff5-5367-5958-9aee-98fffdcd1876
^_low nibble is set to 5, to indicate type 5
^_first two bits set to 1 and 0, respectively
(Notare che i primi due bit di "9" sono già rispettivamente 1 e 0, quindi questo non ha effetto).
Cosa devo hashish?
Probabilmente ti starai chiedendo cosa dovrei hashish. Fondamentalmente hai hash la concatenazione di:
sha1([NamespaceUUID]+[AnyString]);
Aggiungi un prefisso alla stringa con un cosiddetto spazio dei nomi per evitare conflitti di nome.
L' UUID RFC pre-definisce quattro spazi dei nomi per te:
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}
Quindi, potresti hash insieme:
StackOverflowDnsUUID = sha1(Namespace_DNS + "stackoverflow.com");
StackOverflowUrlUUID = sha1(Namespace_URL + "stackoverflow.com");
L'RFC definisce quindi come:
- prendere i 160 bit da SHA1
- e convertirlo in 128 bit di un UUID
L'essenza di base è prendere solo i primi 128 bit, inserire a 5
nel record del tipo e quindi impostare i primi due bit della clock_seq_hi_and_reserved
sezione rispettivamente su 1 e 0.
Altri esempi
Ora che hai una funzione che genera un cosiddetto Nome , puoi avere la funzione (in pseudo-codice):
UUID NameToUUID(UUID NamespaceUUID, String Name)
{
byte[] hash = sha1(NamespaceUUID.ToBytes() + Name.ToBytes());
UUID result;
Copy(hash, result, 16);
result[6] &= 0x0F;
result[6] |= 0x50;
result[8] &= 0x3F;
result[8] |= 0x80;
return result;
}
(Nota che l'endianità del tuo sistema può influenzare gli indici dei byte sopra)
Puoi avere chiamate:
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');
Ora torniamo alla tua domanda
Per gli UUID versione 3 e 5, è necessario fornire lo spazio dei nomi e il nome degli argomenti della riga di comando aggiuntivi. Lo spazio dei nomi è un UUID nella rappresentazione di stringa o un identificatore per gli UUID dello spazio dei nomi predefiniti internamente (attualmente noti sono "ns: DNS", "ns: URL", "ns: OID" e "ns: X500"). Il nome è una stringa di lunghezza arbitraria.
Lo spazio dei nomi è qualsiasi UUID che ti piace. Può essere uno di quelli predefiniti, oppure puoi crearne uno tuo, ad esempio:
UUID Namespace_RectalForeignExtractedObject = '8e884ace-bee4-11e4-8dfc-aa07a5b093db'
Il nome è una stringa di lunghezza arbitraria.
Il nome è solo il testo che desideri venga aggiunto allo spazio dei nomi, quindi sottoposto a hashing e inserito in 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');
Nota : qualsiasi codice rilasciato nel dominio pubblico. Nessuna attribuzione richiesta.