UUID loại 3 và loại 5 chỉ là một kỹ thuật nhồi một hàm băm vào một UUID.
Hàm băm SHA1 xuất ra 160 bit (20 byte); kết quả của băm được chuyển đổi thành UUID.
Với hàm băm 20 byte từ 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
(Lưu ý rằng hai bit đầu tiên của '9' đã là 1 và 0, vì vậy điều này không có tác dụng).
Tôi băm cái gì?
Có lẽ bạn đang thắc mắc rằng tôi phải băm là gì. Về cơ bản, bạn băm sự kết hợp của:
sha1([NamespaceUUID]+[AnyString]);
Bạn đặt trước chuỗi của mình bằng một cái gọi là không gian tên để ngăn xung đột tên.
Các UUID RFC Pre-xác định bốn không gian tên cho bạn:
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}
Vì vậy, bạn có thể băm cùng nhau:
StackOverflowDnsUUID = sha1(Namespace_DNS + "stackoverflow.com");
StackOverflowUrlUUID = sha1(Namespace_URL + "stackoverflow.com");
Sau đó RFC xác định cách:
- lấy 160 bit từ SHA1
- và chuyển đổi nó thành 128 bit của UUID
Ý chính cơ bản là chỉ lấy 128 bit đầu tiên, nhét a 5
vào bản ghi kiểu , sau đó đặt hai bit đầu tiên của clock_seq_hi_and_reserved
phần thành 1 và 0 tương ứng.
Thêm ví dụ
Bây giờ bạn có một hàm tạo ra cái gọi là Tên , bạn có thể có hàm (ở dạng mã giả):
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;
}
(Lưu ý rằng sự cố kết thúc của hệ thống của bạn có thể ảnh hưởng đến các chỉ số của các byte trên)
Bạn có thể có các cuộc gọi:
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');
Bây giờ trở lại câu hỏi của bạn
Đối với UUID phiên bản 3 và phiên bản 5, không gian tên và tên đối số dòng lệnh bổ sung phải được cung cấp. Không gian tên là UUID trong biểu diễn chuỗi hoặc là số nhận dạng cho các UUID không gian tên được xác định trước nội bộ (hiện được biết đến là "ns: DNS", "ns: URL", "ns: OID" và "ns: X500"). Tên là một chuỗi có độ dài tùy ý.
Không gian tên là bất kỳ UUID nào bạn thích. Nó có thể là một trong những cái được xác định trước, hoặc bạn có thể tự tạo, ví dụ:
UUID Namespace_RectalForeignExtractedObject = '8e884ace-bee4-11e4-8dfc-aa07a5b093db'
Tên là một chuỗi có độ dài tùy ý.
Tên chỉ là văn bản bạn muốn thêm vào không gian tên, sau đó được băm và nhồi vào một 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');
Lưu ý : Bất kỳ mã nào được phát hành vào miền công cộng. Không cần ghi công.