Type 3 和 Type 5 UUID 只是一种将哈希填充到 UUID 中的技术:
- 类型 1:填充MAC address+datetime成 128 位
- 类型 3:将 anMD5 hash塞入 128 位
- 类型 4:填充random data128 位
- 类型 5:将SHA1散列塞入 128 位
- 类型 6:顺序 UUID 的非官方想法
编辑:非官方类型 6 现在有官方rfc
SHA1 哈希输出 160 位(20 字节);哈希的结果被转换为 UUID。
使用来自 SHA1 的 20 字节摘要:
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
我要散列什么?
你可能想知道我应该散列的是什么。基本上你散列连接:
sha1( NamespaceUUID+ AnyString);
您在字符串前面加上一个所谓的命名空间,以防止名称冲突。
UUID RFC为您预定义了四个命名空间:
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}
所以,你可以一起散列:
StackOverflowDnsUUID = sha1(Namespace_DNS + "stackoverflow.com");
StackOverflowUrlUUID = sha1(Namespace_URL + "stackoverflow.com");
然后,RFC 定义了如何:
- 从 SHA1 中取出 160 位
- 并将其转换为 128 位的 UUID
基本要点是只取前 128 位,将 a 填充5
到类型记录中,然后将段的前两位clock_seq_hi_and_reserved
分别设置为 1 和 0。
更多示例
现在您有了一个生成所谓Name的函数,您可以拥有该函数(在伪代码中):
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;
}
(注意:系统的字节序会影响上述字节的索引)
现在你可以打电话了:
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');
现在回到你的问题
对于版本 3 和版本 5 UUID,必须提供额外的命令行参数命名空间和名称。命名空间是字符串表示形式的 UUID 或内部预定义命名空间 UUID 的标识符(目前已知为“ns:DNS”、“ns:URL”、“ns:OID”和“ns:X500”)。名称是任意长度的字符串。
命名空间是您喜欢的任何 UUID。它可以是预定义的之一,或者您可以自己制作,例如1:
UUID Namespace_RectalForeignExtractedObject = '8e884ace-bee4-11e4-8dfc-aa07a5b093db'
名称是任意长度的字符串。
该名称只是您希望附加到命名空间的文本,然后经过哈希处理并填充到 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');