类型3和类型5 UUID只是将哈希填充到UUID中的一种技术。
- 类型1:将MAC地址+日期时间填充到128位中
- 类型3:将MD5哈希填充到128位中
- 类型4:将随机数据填充到128位中
- 类型5:将SHA1哈希填充到128位中
- 类型6:顺序UUID的非正式概念
SHA1哈希输出160位(20字节);哈希的结果将转换为UUID。
使用SHA1中的20字节哈希:
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
(请注意,“ 9”的前两位已经分别是1和0,因此无效)。
我要哈希什么?
您可能想知道我应该算什么。基本上,您哈希以下内容的串联:
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位,5
在类型记录中填充a ,然后将该clock_seq_hi_and_reserved
节的前两位分别设置为1和0。
更多例子
现在您有了一个生成所谓Name的函数,您可以拥有该函数(以伪代码):
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;
}
(请注意,系统的字节顺序会影响上述字节的索引)
您可以拨打电话:
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你喜欢。它可以是预定义的之一,也可以自己组成,例如:
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');
注意:任何发布到公共领域的代码。无需注明出处。