Type 3 和 Type 5 UUID 只是一种将 hash 填充到 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位,在type记录中填充一个5,然后设置@987654333的前两位@ 部分分别为 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');