| < draft-mealling-uuid-urn-01.txt | draft-mealling-uuid-urn-02.txt > | |||
|---|---|---|---|---|
| Network Working Group P. Leach | Network Working Group P. Leach | |||
| Internet-Draft Microsoft | Internet-Draft Microsoft | |||
| Expires: April 2, 2004 M. Mealling | Expires: July 28, 2004 M. Mealling | |||
| VeriSign, Inc. | VeriSign, Inc. | |||
| R. Salz | R. Salz | |||
| DataPower Technology, Inc. | DataPower Technology, Inc. | |||
| October 3, 2003 | January 28, 2004 | |||
| A UUID URN Namespace | A UUID URN Namespace | |||
| draft-mealling-uuid-urn-01.txt | draft-mealling-uuid-urn-02.txt | |||
| Status of this Memo | Status of this Memo | |||
| This document is an Internet-Draft and is in full conformance with | This document is an Internet-Draft and is in full conformance with | |||
| all provisions of Section 10 of RFC2026. | all provisions of Section 10 of RFC2026. | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF), its areas, and its working groups. Note that other | Task Force (IETF), its areas, and its working groups. Note that other | |||
| groups may also distribute working documents as Internet-Drafts. | groups may also distribute working documents as Internet-Drafts. | |||
| skipping to change at page 1, line 34 ¶ | skipping to change at page 1, line 34 ¶ | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| The list of current Internet-Drafts can be accessed at http:// | The list of current Internet-Drafts can be accessed at http:// | |||
| www.ietf.org/ietf/1id-abstracts.txt. | www.ietf.org/ietf/1id-abstracts.txt. | |||
| The list of Internet-Draft Shadow Directories can be accessed at | The list of Internet-Draft Shadow Directories can be accessed at | |||
| http://www.ietf.org/shadow.html. | http://www.ietf.org/shadow.html. | |||
| This Internet-Draft will expire on April 2, 2004. | This Internet-Draft will expire on July 28, 2004. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (C) The Internet Society (2003). All Rights Reserved. | Copyright (C) The Internet Society (2004). All Rights Reserved. | |||
| Abstract | Abstract | |||
| This specification defines a Uniform Resource Name namespace for | This specification defines a Uniform Resource Name namespace for | |||
| UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally | UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally | |||
| Unique IDentifier). A UUID is 128 bits long, and can provide a | Unique IDentifier). A UUID is 128 bits long, and can provide a | |||
| guarantee of uniqueness across space and time. UUIDs were originally | guarantee of uniqueness across space and time. UUIDs were originally | |||
| used in the Network Computing System (NCS) [1] and later in the Open | used in the Network Computing System (NCS) [1] and later in the Open | |||
| Software Foundation's (OSF) Distributed Computing Environment [2]. | Software Foundation's (OSF) Distributed Computing Environment [2]. | |||
| This specification is derived from the latter specification with the | This specification is derived from the latter specification with the | |||
| kind permission of the OSF (now known as The Open Group). Earlier | kind permission of the OSF (now known as The Open Group). Earlier | |||
| versions of this document never left draft stage; this document | versions of this document never left draft stage; this document | |||
| incorporates that information here. | incorporates that information here. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 2. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . 3 | 2. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 3. Namespace Registration Template . . . . . . . . . . . . . . 3 | 3. Namespace Registration Template . . . . . . . . . . . . . . 3 | |||
| 4. Specification . . . . . . . . . . . . . . . . . . . . . . . 6 | 4. Specification . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
| 4.1 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 | 4.1 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 | |||
| 4.1.1 Variant . . . . . . . . . . . . . . . . . . . . . . . . . . 6 | 4.1.1 Variant . . . . . . . . . . . . . . . . . . . . . . . . . . 6 | |||
| 4.1.2 Layout and byte order . . . . . . . . . . . . . . . . . . . 6 | 4.1.2 Layout and byte order . . . . . . . . . . . . . . . . . . . 6 | |||
| 4.1.3 Version . . . . . . . . . . . . . . . . . . . . . . . . . . 8 | 4.1.3 Version . . . . . . . . . . . . . . . . . . . . . . . . . . 7 | |||
| 4.1.4 Timestamp . . . . . . . . . . . . . . . . . . . . . . . . . 8 | 4.1.4 Timestamp . . . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 4.1.5 Clock sequence . . . . . . . . . . . . . . . . . . . . . . . 8 | 4.1.5 Clock sequence . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 4.1.6 Node . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 | 4.1.6 Node . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 4.1.7 Nil UUID . . . . . . . . . . . . . . . . . . . . . . . . . . 10 | 4.1.7 Nil UUID . . . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 4.2 Algorithms for creating a time-based UUID . . . . . . . . . 10 | 4.2 Algorithms for creating a time-based UUID . . . . . . . . . 10 | |||
| 4.2.1 Basic algorithm . . . . . . . . . . . . . . . . . . . . . . 10 | 4.2.1 Basic algorithm . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 4.2.2 Generation details . . . . . . . . . . . . . . . . . . . . . 12 | 4.2.2 Generation details . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 4.3 Algorithm for creating a name-based UUID . . . . . . . . . . 13 | 4.3 Algorithm for creating a name-based UUID . . . . . . . . . . 12 | |||
| 4.4 Algorithms for creating a UUID from truly random or | 4.4 Algorithms for creating a UUID from truly random or | |||
| pseudo-random numbers . . . . . . . . . . . . . . . . . . . 14 | pseudo-random numbers . . . . . . . . . . . . . . . . . . . 13 | |||
| 4.5 Node IDs that do not identify the host . . . . . . . . . . . 15 | 4.5 Node IDs that do not identify the host . . . . . . . . . . . 14 | |||
| 5. Community Considerations . . . . . . . . . . . . . . . . . . 16 | 5. Community Considerations . . . . . . . . . . . . . . . . . . 15 | |||
| 6. Security Considerations . . . . . . . . . . . . . . . . . . 17 | 6. Security Considerations . . . . . . . . . . . . . . . . . . 15 | |||
| 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . 17 | 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . 16 | |||
| Normative References . . . . . . . . . . . . . . . . . . . . 17 | Normative References . . . . . . . . . . . . . . . . . . . . 16 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 18 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 16 | |||
| A. Appendix A - Sample Implementation . . . . . . . . . . . . . 18 | A. Appendix A - Sample Implementation . . . . . . . . . . . . . 17 | |||
| B. Appendix B - Sample output of utest . . . . . . . . . . . . 29 | B. Appendix B - Sample output of utest . . . . . . . . . . . . 28 | |||
| C. Appendix C - Some name space IDs . . . . . . . . . . . . . . 29 | C. Appendix C - Some name space IDs . . . . . . . . . . . . . . 28 | |||
| Intellectual Property and Copyright Statements . . . . . . . 31 | Intellectual Property and Copyright Statements . . . . . . . 30 | |||
| 1. Introduction | 1. Introduction | |||
| This specification defines a Uniform Resource Name namespace for | This specification defines a Uniform Resource Name namespace for | |||
| UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally | UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally | |||
| Unique IDentifier). A UUID is 128 bits long, and requires no central | Unique IDentifier). A UUID is 128 bits long, and requires no central | |||
| registration process. | registration process. | |||
| The information here is meant to be a concise guide for those wishing | The information here is meant to be a concise guide for those wishing | |||
| to implement services using UUIDs as URNs. Nothing in this document | to implement services using UUIDs as URNs. Nothing in this document | |||
| skipping to change at page 3, line 28 ¶ | skipping to change at page 3, line 28 ¶ | |||
| One of the main reasons for using UUIDs is that no centralized | One of the main reasons for using UUIDs is that no centralized | |||
| authority is required to administer them (although one format uses | authority is required to administer them (although one format uses | |||
| IEEE 802.1 node identifiers, others do not). As a result, generation | IEEE 802.1 node identifiers, others do not). As a result, generation | |||
| on demand can be completely automated, and they can be used for a | on demand can be completely automated, and they can be used for a | |||
| wide variety of purposes. The UUID generation algorithm described | wide variety of purposes. The UUID generation algorithm described | |||
| here supports very high allocation rates: 10 million per second per | here supports very high allocation rates: 10 million per second per | |||
| machine if necessary, so that they could even be used as transaction | machine if necessary, so that they could even be used as transaction | |||
| IDs. | IDs. | |||
| UUIDs are of a fixed size (128-bits) which is reasonably small | UUIDs are of a fixed size (128 bits) which is reasonably small | |||
| relative to other alternatives. This lends itself well to sorting, | relative to other alternatives. This lends itself well to sorting, | |||
| ordering, and hashing of all sorts, storing in databases, simple | ordering, and hashing of all sorts, storing in databases, simple | |||
| allocation, and ease of programming in general. | allocation, and ease of programming in general. | |||
| Since UUIDs are unique and persistent, they make excellent Uniform | Since UUIDs are unique and persistent, they make excellent Uniform | |||
| Resource Names. The unique ability to generate a new UUID without a | Resource Names. The unique ability to generate a new UUID without a | |||
| registration process allows for UUIDs to be one of the URNs with the | registration process allows for UUIDs to be one of the URNs with the | |||
| lowest minting cost. | lowest minting cost. | |||
| 3. Namespace Registration Template | 3. Namespace Registration Template | |||
| skipping to change at page 7, line 38 ¶ | skipping to change at page 7, line 34 ¶ | |||
| bit integer clock sequence | bit integer clock sequence | |||
| node unsigned 48 10-15 The spatially unique | node unsigned 48 10-15 The spatially unique | |||
| bit integer node identifier | bit integer node identifier | |||
| In the absence of explicit application or presentation protocol | In the absence of explicit application or presentation protocol | |||
| specification to the contrary, a UUID is encoded as a 128-bit object, | specification to the contrary, a UUID is encoded as a 128-bit object, | |||
| as follows: the fields are encoded as 16 octets, with the sizes and | as follows: the fields are encoded as 16 octets, with the sizes and | |||
| order of the fields defined above, and with each field encoded with | order of the fields defined above, and with each field encoded with | |||
| the Most Significant Byte first (this is known as network byte | the Most Significant Byte first (this is known as network byte | |||
| order). | order). Note that the field names, particularly for multiplexed | |||
| fields, follow historical practice. | ||||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | time_low | | | time_low | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | time_mid | time_hi_and_version | | | time_mid | time_hi_and_version | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| |clk_seq_hi_res | clk_seq_low | node (0-1) | | |clk_seq_hi_res | clk_seq_low | node (0-1) | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | node (2-5) | | | node (2-5) | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| 4.1.3 Version | 4.1.3 Version | |||
| The version number is in the most significant four bits of the time | The version number is in the most significant four bits of the time | |||
| stamp (time_hi_and_version). | stamp (bits four through seven of the time_hi_and_version field). | |||
| The following table lists the currently-defined versions for this | The following table lists the currently-defined versions for this | |||
| UUID variant. | UUID variant. | |||
| Msb0 Msb1 Msb2 Msb3 Version Description | Msb0 Msb1 Msb2 Msb3 Version Description | |||
| 0 0 0 1 1 The time-based version | 0 0 0 1 1 The time-based version | |||
| specified in this document. | specified in this document. | |||
| 0 0 1 0 2 DCE Security version, with | 0 0 1 0 2 DCE Security version, with | |||
| skipping to change at page 9, line 36 ¶ | skipping to change at page 9, line 34 ¶ | |||
| The initial value MUST NOT be correlated to the node identifier. | The initial value MUST NOT be correlated to the node identifier. | |||
| For UUID version 3, it is a 14-bit value constructed from a name as | For UUID version 3, it is a 14-bit value constructed from a name as | |||
| described in Section 4.3. | described in Section 4.3. | |||
| For UUID version 4, it is a randomly or pseudo-randomly generated | For UUID version 4, it is a randomly or pseudo-randomly generated | |||
| 14-bit value as described in Section 4.4. | 14-bit value as described in Section 4.4. | |||
| 4.1.6 Node | 4.1.6 Node | |||
| For UUID version 1, the node field consists of the IEEE address, | For UUID version 1, the node field consists of an IEEE address, | |||
| usually the host address. For systems with multiple IEEE 802 | usually the host address. For systems with multiple IEEE 802 | |||
| addresses, any available address can be used. The lowest addressed | addresses, any available address can be used. The lowest addressed | |||
| octet (octet number 10) contains the global/local bit and the | octet (octet number 10) contains the global/local bit and the | |||
| unicast/multicast bit, and is the first octet of the address | unicast/multicast bit, and is the first octet of the address | |||
| transmitted on an 802.3 LAN. | transmitted on an 802.3 LAN. | |||
| For systems with no IEEE address, a randomly or pseudo-randomly | For systems with no IEEE address, a randomly or pseudo-randomly | |||
| generated value may be used; see Section 4.5. The multicast bit must | generated value may be used; see Section 4.5. The multicast bit must | |||
| be set in such addresses, in order that they will never conflict with | be set in such addresses, in order that they will never conflict with | |||
| addresses obtained from network cards. | addresses obtained from network cards. | |||
| skipping to change at page 13, line 35 ¶ | skipping to change at page 13, line 9 ¶ | |||
| The version 3 UUID is meant for generating UUIDs from "names" that | The version 3 UUID is meant for generating UUIDs from "names" that | |||
| are drawn from, and unique within, some "name space." The concept of | are drawn from, and unique within, some "name space." The concept of | |||
| name and name space should be broadly construed, and not limited to | name and name space should be broadly construed, and not limited to | |||
| textual names. For example, some name spaces are the domain name | textual names. For example, some name spaces are the domain name | |||
| system, URLs, ISO Object IDs (OIDs), X.500 Distinguished Names (DNs), | system, URLs, ISO Object IDs (OIDs), X.500 Distinguished Names (DNs), | |||
| and reserved words in a programming language. The mechanisms or | and reserved words in a programming language. The mechanisms or | |||
| conventions for allocating names from, and ensuring their uniqueness | conventions for allocating names from, and ensuring their uniqueness | |||
| within, their name spaces are beyond the scope of this specification. | within, their name spaces are beyond the scope of this specification. | |||
| The requirements for version 3 UUIDs are as follows: | The requirements for version 3 UUIDs are as follows: | |||
| o The UUIDs generated at different times from the same name in the | o The UUIDs generated at different times from the same name in the | |||
| same namespace MUST be equal | same namespace MUST be equal | |||
| o The UUIDs generated from two different names in the same namespace | o The UUIDs generated from two different names in the same namespace | |||
| should be different (with very high probability) | should be different (with very high probability) | |||
| o The UUIDs generated from the same name in two different namespaces | o The UUIDs generated from the same name in two different namespaces | |||
| should be different with (very high probability) | should be different with (very high probability) | |||
| o If two UUIDs that were generated from names are equal, then they | o If two UUIDs that were generated from names are equal, then they | |||
| were generated from the same name in the same namespace (with very | were generated from the same name in the same namespace (with very | |||
| high probability). | high probability). | |||
| The algorithm for generating the a UUID from a name and a name space | The algorithm for generating the a UUID from a name and a name space | |||
| are as follows: | are as follows: | |||
| o Allocate a UUID to use as a "name space ID" for all UUIDs | o Allocate a UUID to use as a "name space ID" for all UUIDs | |||
| generated from names in that name space; see Appendix C for some | generated from names in that name space; see Appendix C for some | |||
| pre-defined values | pre-defined values | |||
| o Convert the name to a canonical sequence of octets (as defined by | o Convert the name to a canonical sequence of octets (as defined by | |||
| the standards or conventions of its name space); put the name | the standards or conventions of its name space); put the name | |||
| space ID in network byte order | space ID in network byte order | |||
| o Compute the MD5 [3] hash of the name space ID concatenated with | o Compute the MD5 [3] hash of the name space ID concatenated with | |||
| the name | the name | |||
| o Set octets zero through three of the time_low field to octets zero | o Set octets zero through three of the time_low field to octets zero | |||
| through three of the MD5 hash | through three of the MD5 hash | |||
| o Set octets zero and one of the time_mid field to octets four and | o Set octets zero and one of the time_mid field to octets four and | |||
| five of the MD5 hash | five of the MD5 hash | |||
| o Set octets zero and one of the time_hi_and_version field to octets | o Set octets zero and one of the time_hi_and_version field to octets | |||
| six and seven of the MD5 hash | six and seven of the MD5 hash | |||
| o Set the four most significant bits (bits 12 through 15) of the | o Set the four most significant bits (bits 12 through 15) of the | |||
| time_hi_and_version field to the four-bit version number from | time_hi_and_version field to the four-bit version number from | |||
| Section 4.1.3. | Section 4.1.3. | |||
| o Set the clock_seq_hi_and_reserved field to octet eight of the MD5 | o Set the clock_seq_hi_and_reserved field to octet eight of the MD5 | |||
| hash | hash | |||
| o Set the two most significant bits (bits six and seven) of the | ||||
| o Set the two most significant bits (bits 6 and 7) of the | ||||
| clock_seq_hi_and_reserved to zero and one, respectively. | clock_seq_hi_and_reserved to zero and one, respectively. | |||
| o Set the clock_seq_low field to octet nine of the MD5 hash | o Set the clock_seq_low field to octet nine of the MD5 hash | |||
| o Set octets zero through five of the node field to octets then | o Set octets zero through five of the node field to octets then | |||
| through fifteen of the MD5 hash | through fifteen of the MD5 hash | |||
| o Convert the resulting UUID to local byte order. | o Convert the resulting UUID to local byte order. | |||
| 4.4 Algorithms for creating a UUID from truly random or pseudo-random | 4.4 Algorithms for creating a UUID from truly random or pseudo-random | |||
| numbers | numbers | |||
| The version 4 UUID is meant for generating UUIDs from truly-random or | The version 4 UUID is meant for generating UUIDs from truly-random or | |||
| pseudo-random numbers. | pseudo-random numbers. | |||
| The algorithm is as follows: | The algorithm is as follows: | |||
| o Set the two most significant bits (bits six and seven) of the | o Set the two most significant bits (bits six and seven) of the | |||
| clock_seq_hi_and_reserved to zero and one, respectively. | clock_seq_hi_and_reserved to zero and one, respectively. | |||
| o Set the four most significant bits (bits 12 through 15) of the | o Set the four most significant bits (bits 12 through 15) of the | |||
| time_hi_and_version field to the four-bit version number from | time_hi_and_version field to the four-bit version number from | |||
| Section 4.1.3. | Section 4.1.3. | |||
| o Set all the other bits to randomly (or pseudo-randomly) chosen | o Set all the other bits to randomly (or pseudo-randomly) chosen | |||
| values. | values. | |||
| See Section 4.5 for a discussion on random numbers. | See Section 4.5 for a discussion on random numbers. | |||
| 4.5 Node IDs that do not identify the host | 4.5 Node IDs that do not identify the host | |||
| This section describes how to generate a version 1 UUID if an IEEE | This section describes how to generate a version 1 UUID if an IEEE | |||
| 802 address is not available, or its use is not desired. | 802 address is not available, or its use is not desired. | |||
| skipping to change at page 18, line 15 ¶ | skipping to change at page 17, line 4 ¶ | |||
| Authors' Addresses | Authors' Addresses | |||
| Paul J. Leach | Paul J. Leach | |||
| Microsoft | Microsoft | |||
| 1 Microsoft Way | 1 Microsoft Way | |||
| Redmond, WA 98052 | Redmond, WA 98052 | |||
| US | US | |||
| Phone: +1 425-882-8080 | Phone: +1 425-882-8080 | |||
| EMail: paulle@microsoft.com | EMail: paulle@microsoft.com | |||
| Michael Mealling | Michael Mealling | |||
| VeriSign, Inc. | VeriSign, Inc. | |||
| 21345 Ridgetop Circle | 21345 Ridgetop Circle | |||
| Dulles, VA 21345 | Dulles, VA 21345 | |||
| US | US | |||
| Phone: +1 678-581-9656 | Phone: +1 770-717-0732 | |||
| EMail: michael@neonym.net | ||||
| URI: http://www.verisignlabs.com | URI: http://www.verisignlabs.com | |||
| Rich Salz | Rich Salz | |||
| DataPower Technology, Inc. | DataPower Technology, Inc. | |||
| 1 Alewife Center | 1 Alewife Center | |||
| Cambridge, MA 02142 | Cambridge, MA 02142 | |||
| US | US | |||
| Phone: +1 617-864-0455 | Phone: +1 617-864-0455 | |||
| EMail: rsalz@datapower.com | EMail: rsalz@datapower.com | |||
| skipping to change at page 19, line 18 ¶ | skipping to change at page 18, line 7 ¶ | |||
| ** To anyone who acknowledges that this file is provided "AS IS" | ** To anyone who acknowledges that this file is provided "AS IS" | |||
| ** without any express or implied warranty: permission to use, copy, | ** without any express or implied warranty: permission to use, copy, | |||
| ** modify, and distribute this file for any purpose is hereby | ** modify, and distribute this file for any purpose is hereby | |||
| ** granted without fee, provided that the above copyright notices and | ** granted without fee, provided that the above copyright notices and | |||
| ** this notice appears in all source code copies, and that none of | ** this notice appears in all source code copies, and that none of | |||
| ** the names of Open Software Foundation, Inc., Hewlett-Packard | ** the names of Open Software Foundation, Inc., Hewlett-Packard | |||
| ** Company, or Digital Equipment Corporation be used in advertising | ** Company, or Digital Equipment Corporation be used in advertising | |||
| ** or publicity pertaining to distribution of the software without | ** or publicity pertaining to distribution of the software without | |||
| ** specific, written prior permission. Neither Open Software | ** specific, written prior permission. Neither Open Software | |||
| ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital | ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital | |||
| ** Equipment Corporation makes any representations about the | ** Equipment Corporation makes any representations about the suitability | |||
| suitability | ||||
| ** of this software for any purpose. | ** of this software for any purpose. | |||
| */ | */ | |||
| uuid.h | uuid.h | |||
| #include "copyrt.h" | #include "copyrt.h" | |||
| #undef uuid_t | #undef uuid_t | |||
| typedef struct { | typedef struct { | |||
| unsigned32 time_low; | unsigned32 time_low; | |||
| unsigned16 time_mid; | unsigned16 time_mid; | |||
| skipping to change at page 19, line 44 ¶ | skipping to change at page 18, line 32 ¶ | |||
| } uuid_t; | } uuid_t; | |||
| /* uuid_create -- generate a UUID */ | /* uuid_create -- generate a UUID */ | |||
| int uuid_create(uuid_t * uuid); | int uuid_create(uuid_t * uuid); | |||
| /* uuid_create_from_name -- create a UUID using a "name" | /* uuid_create_from_name -- create a UUID using a "name" | |||
| from a "name space" */ | from a "name space" */ | |||
| void uuid_create_from_name( | void uuid_create_from_name( | |||
| uuid_t *uuid, /* resulting UUID */ | uuid_t *uuid, /* resulting UUID */ | |||
| uuid_t nsid, /* UUID of the namespace */ | uuid_t nsid, /* UUID of the namespace */ | |||
| void *name, /* the name from which to generate a UUID | void *name, /* the name from which to generate a UUID */ | |||
| */ | ||||
| int namelen /* the length of the name */ | int namelen /* the length of the name */ | |||
| ); | ); | |||
| /* uuid_compare -- Compare two UUID's "lexically" and return | /* uuid_compare -- Compare two UUID's "lexically" and return | |||
| -1 u1 is lexically before u2 | -1 u1 is lexically before u2 | |||
| 0 u1 is equal to u2 | 0 u1 is equal to u2 | |||
| 1 u1 is lexically after u2 | 1 u1 is lexically after u2 | |||
| Note that lexical ordering is not temporal ordering! | Note that lexical ordering is not temporal ordering! | |||
| */ | */ | |||
| int uuid_compare(uuid_t *u1, uuid_t *u2); | int uuid_compare(uuid_t *u1, uuid_t *u2); | |||
| uuid.c | uuid.c | |||
| #include "copyrt.h" | #include "copyrt.h" | |||
| #include <string.h> | #include <string.h> | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include <stdlib.h> | #include <stdlib.h> | |||
| skipping to change at page 20, line 47 ¶ | skipping to change at page 19, line 36 ¶ | |||
| int f; | int f; | |||
| /* acquire system-wide lock so we're alone */ | /* acquire system-wide lock so we're alone */ | |||
| LOCK; | LOCK; | |||
| /* get time, node ID, saved state from non-volatile storage */ | /* get time, node ID, saved state from non-volatile storage */ | |||
| get_current_time(×tamp); | get_current_time(×tamp); | |||
| get_ieee_node_identifier(&node); | get_ieee_node_identifier(&node); | |||
| f = read_state(&clockseq, &last_time, &last_node); | f = read_state(&clockseq, &last_time, &last_node); | |||
| /* if no NV state, or if clock went backwards, or node ID | /* if no NV state, or if clock went backwards, or node ID changed | |||
| changed | ||||
| (e.g., new network card) change clockseq */ | (e.g., new network card) change clockseq */ | |||
| if (!f || memcmp(&node, &last_node, sizeof node)) | if (!f || memcmp(&node, &last_node, sizeof node)) | |||
| clockseq = true_random(); | clockseq = true_random(); | |||
| else if (timestamp < last_time) | else if (timestamp < last_time) | |||
| clockseq++; | clockseq++; | |||
| /* save the state for next time */ | /* save the state for next time */ | |||
| write_state(clockseq, timestamp, node); | write_state(clockseq, timestamp, node); | |||
| UNLOCK; | UNLOCK; | |||
| skipping to change at page 22, line 16 ¶ | skipping to change at page 21, line 4 ¶ | |||
| return 0; | return 0; | |||
| fread(&st, sizeof st, 1, fp); | fread(&st, sizeof st, 1, fp); | |||
| fclose(fp); | fclose(fp); | |||
| inited = 1; | inited = 1; | |||
| } | } | |||
| *clockseq = st.cs; | *clockseq = st.cs; | |||
| *timestamp = st.ts; | *timestamp = st.ts; | |||
| *node = st.node; | *node = st.node; | |||
| return 1; | return 1; | |||
| } | } | |||
| /* write_state -- save UUID generator state back to non-volatile storage */ | ||||
| /* write_state -- save UUID generator state back to non-volatile | ||||
| storage */ | ||||
| void write_state(unsigned16 clockseq, uuid_time_t timestamp, | void write_state(unsigned16 clockseq, uuid_time_t timestamp, | |||
| uuid_node_t node) | uuid_node_t node) | |||
| { | { | |||
| static int inited = 0; | static int inited = 0; | |||
| static uuid_time_t next_save; | static uuid_time_t next_save; | |||
| FILE* fp; | FILE* fp; | |||
| if (!inited) { | if (!inited) { | |||
| next_save = timestamp; | next_save = timestamp; | |||
| inited = 1; | inited = 1; | |||
| skipping to change at page 22, line 44 ¶ | skipping to change at page 21, line 30 ¶ | |||
| st.node = node; | st.node = node; | |||
| if (timestamp >= next_save) { | if (timestamp >= next_save) { | |||
| fp = fopen("state", "wb"); | fp = fopen("state", "wb"); | |||
| fwrite(&st, sizeof st, 1, fp); | fwrite(&st, sizeof st, 1, fp); | |||
| fclose(fp); | fclose(fp); | |||
| /* schedule next save for 10 seconds from now */ | /* schedule next save for 10 seconds from now */ | |||
| next_save = timestamp + (10 * 10 * 1000 * 1000); | next_save = timestamp + (10 * 10 * 1000 * 1000); | |||
| } | } | |||
| } | } | |||
| /* get-current_time -- get time as 60-bit 100ns ticks since UUID | /* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch. | |||
| epoch. | ||||
| Compensate for the fact that real clock resolution is | Compensate for the fact that real clock resolution is | |||
| less than 100ns. */ | less than 100ns. */ | |||
| void get_current_time(uuid_time_t *timestamp) | void get_current_time(uuid_time_t *timestamp) | |||
| { | { | |||
| static int inited = 0; | static int inited = 0; | |||
| static uuid_time_t time_last; | static uuid_time_t time_last; | |||
| static unsigned16 uuids_this_tick; | static unsigned16 uuids_this_tick; | |||
| uuid_time_t time_now; | uuid_time_t time_now; | |||
| if (!inited) { | if (!inited) { | |||
| get_system_time(&time_now); | get_system_time(&time_now); | |||
| uuids_this_tick = UUIDS_PER_TICK; | uuids_this_tick = UUIDS_PER_TICK; | |||
| inited = 1; | inited = 1; | |||
| } | } | |||
| for ( ; ; ) { | for ( ; ; ) { | |||
| get_system_time(&time_now); | get_system_time(&time_now); | |||
| /* if clock reading changed since last UUID generated, */ | /* if clock reading changed since last UUID generated, */ | |||
| skipping to change at page 23, line 25 ¶ | skipping to change at page 22, line 13 ¶ | |||
| /* reset count of uuids gen'd with this clock reading */ | /* reset count of uuids gen'd with this clock reading */ | |||
| uuids_this_tick = 0; | uuids_this_tick = 0; | |||
| break; | break; | |||
| } | } | |||
| if (uuids_this_tick < UUIDS_PER_TICK) { | if (uuids_this_tick < UUIDS_PER_TICK) { | |||
| uuids_this_tick++; | uuids_this_tick++; | |||
| break; | break; | |||
| } | } | |||
| /* going too fast for our clock; spin */ | /* going too fast for our clock; spin */ | |||
| } | } | |||
| /* add the count of uuids to low order bits of the clock reading | /* add the count of uuids to low order bits of the clock reading */ | |||
| */ | ||||
| *timestamp = time_now + uuids_this_tick; | *timestamp = time_now + uuids_this_tick; | |||
| } | } | |||
| /* true_random -- generate a crypto-quality random number. | /* true_random -- generate a crypto-quality random number. | |||
| **This sample doesn't do that.** */ | **This sample doesn't do that.** */ | |||
| static unsigned16 true_random(void) | static unsigned16 true_random(void) | |||
| { | { | |||
| static int inited = 0; | static int inited = 0; | |||
| uuid_time_t time_now; | uuid_time_t time_now; | |||
| if (!inited) { | if (!inited) { | |||
| get_system_time(&time_now); | get_system_time(&time_now); | |||
| time_now = time_now / UUIDS_PER_TICK; | time_now = time_now / UUIDS_PER_TICK; | |||
| srand((unsigned int)(((time_now >> 32) ^ time_now) & | srand((unsigned int)(((time_now >> 32) ^ time_now) & 0xffffffff)); | |||
| 0xffffffff)); | ||||
| inited = 1; | inited = 1; | |||
| } | } | |||
| return rand(); | return rand(); | |||
| } | } | |||
| /* uuid_create_from_name -- create a UUID using a "name" from a "name | /* uuid_create_from_name -- create a UUID using a "name" from a "name | |||
| space" */ | space" */ | |||
| void uuid_create_from_name(uuid_t *uuid, uuid_t nsid, void *name, | void uuid_create_from_name(uuid_t *uuid, uuid_t nsid, void *name, | |||
| int namelen) | int namelen) | |||
| skipping to change at page 24, line 23 ¶ | skipping to change at page 23, line 11 ¶ | |||
| MD5Init(&c); | MD5Init(&c); | |||
| MD5Update(&c, &net_nsid, sizeof net_nsid); | MD5Update(&c, &net_nsid, sizeof net_nsid); | |||
| MD5Update(&c, name, namelen); | MD5Update(&c, name, namelen); | |||
| MD5Final(hash, &c); | MD5Final(hash, &c); | |||
| /* the hash is in network byte order at this point */ | /* the hash is in network byte order at this point */ | |||
| format_uuid_v3(uuid, hash); | format_uuid_v3(uuid, hash); | |||
| } | } | |||
| /* format_uuid_v3 -- make a UUID from a (pseudo)random 128-bit number | /* format_uuid_v3 -- make a UUID from a (pseudo)random 128-bit number */ | |||
| */ | ||||
| void format_uuid_v3(uuid_t *uuid, unsigned char hash[16]) | void format_uuid_v3(uuid_t *uuid, unsigned char hash[16]) | |||
| { | { | |||
| /* convert UUID to local byte order */ | /* convert UUID to local byte order */ | |||
| memcpy(uuid, hash, sizeof *uuid); | memcpy(uuid, hash, sizeof *uuid); | |||
| ntohl(uuid->time_low); | ntohl(uuid->time_low); | |||
| ntohs(uuid->time_mid); | ntohs(uuid->time_mid); | |||
| ntohs(uuid->time_hi_and_version); | ntohs(uuid->time_hi_and_version); | |||
| /* put in the variant and version bits */ | /* put in the variant and version bits */ | |||
| uuid->time_hi_and_version &= 0x0FFF; | uuid->time_hi_and_version &= 0x0FFF; | |||
| skipping to change at page 24, line 49 ¶ | skipping to change at page 23, line 36 ¶ | |||
| /* uuid_compare -- Compare two UUID's "lexically" and return */ | /* uuid_compare -- Compare two UUID's "lexically" and return */ | |||
| #define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1; | #define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1; | |||
| int uuid_compare(uuid_t *u1, uuid_t *u2) | int uuid_compare(uuid_t *u1, uuid_t *u2) | |||
| { | { | |||
| int i; | int i; | |||
| CHECK(u1->time_low, u2->time_low); | CHECK(u1->time_low, u2->time_low); | |||
| CHECK(u1->time_mid, u2->time_mid); | CHECK(u1->time_mid, u2->time_mid); | |||
| CHECK(u1->time_hi_and_version, u2->time_hi_and_version); | CHECK(u1->time_hi_and_version, u2->time_hi_and_version); | |||
| CHECK(u1->clock_seq_hi_and_reserved, | CHECK(u1->clock_seq_hi_and_reserved, u2->clock_seq_hi_and_reserved); | |||
| u2->clock_seq_hi_and_reserved); | ||||
| CHECK(u1->clock_seq_low, u2->clock_seq_low) | CHECK(u1->clock_seq_low, u2->clock_seq_low) | |||
| for (i = 0; i < 6; i++) { | for (i = 0; i < 6; i++) { | |||
| if (u1->node[i] < u2->node[i]) | if (u1->node[i] < u2->node[i]) | |||
| return -1; | return -1; | |||
| if (u1->node[i] > u2->node[i]) | if (u1->node[i] > u2->node[i]) | |||
| return 1; | return 1; | |||
| } | } | |||
| return 0; | return 0; | |||
| } | } | |||
| #undef CHECK | #undef CHECK | |||
| skipping to change at page 27, line 4 ¶ | skipping to change at page 25, line 40 ¶ | |||
| if (fp) { | if (fp) { | |||
| fwrite(&saved_node, sizeof saved_node, 1, fp); | fwrite(&saved_node, sizeof saved_node, 1, fp); | |||
| fclose(fp); | fclose(fp); | |||
| } | } | |||
| } | } | |||
| inited = 1; | inited = 1; | |||
| } | } | |||
| *node = saved_node; | *node = saved_node; | |||
| } | } | |||
| /* system dependent call to get the current system time. Returned as | /* system dependent call to get the current system time. Returned as | |||
| 100ns ticks since UUID epoch, but resolution may be less than | 100ns ticks since UUID epoch, but resolution may be less than 100ns. */ | |||
| 100ns. */ | ||||
| #ifdef _WINDOWS_ | #ifdef _WINDOWS_ | |||
| void get_system_time(uuid_time_t *uuid_time) | void get_system_time(uuid_time_t *uuid_time) | |||
| { | { | |||
| ULARGE_INTEGER time; | ULARGE_INTEGER time; | |||
| /* NT keeps time in FILETIME format which is 100ns ticks since | /* NT keeps time in FILETIME format which is 100ns ticks since | |||
| Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. | Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. | |||
| The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) | The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) | |||
| + 18 years and 5 leap days. */ | + 18 years and 5 leap days. */ | |||
| skipping to change at page 28, line 12 ¶ | skipping to change at page 26, line 49 ¶ | |||
| void get_system_time(uuid_time_t *uuid_time) | void get_system_time(uuid_time_t *uuid_time) | |||
| { | { | |||
| struct timeval tp; | struct timeval tp; | |||
| gettimeofday(&tp, (struct timezone *)0); | gettimeofday(&tp, (struct timezone *)0); | |||
| /* Offset between UUID formatted times and Unix formatted times. | /* Offset between UUID formatted times and Unix formatted times. | |||
| UUID UTC base time is October 15, 1582. | UUID UTC base time is October 15, 1582. | |||
| Unix base time is January 1, 1970.*/ | Unix base time is January 1, 1970.*/ | |||
| *uuid_time = (tp.tv_sec * 10000000) + (tp.tv_usec * 10) | *uuid_time = ((unsigned64)tp.tv_sec * 10000000) | |||
| + ((unsigned64)tp.tv_usec * 10) | ||||
| + I64(0x01B21DD213814000); | + I64(0x01B21DD213814000); | |||
| } | } | |||
| void get_random_info(char seed[16]) | void get_random_info(char seed[16]) | |||
| { | { | |||
| MD5_CTX c; | MD5_CTX c; | |||
| struct { | struct { | |||
| struct sysinfo s; | struct sysinfo s; | |||
| struct timeval t; | struct timeval t; | |||
| char hostname[257]; | char hostname[257]; | |||
| } r; | } r; | |||
| skipping to change at page 31, line 29 ¶ | skipping to change at page 30, line 29 ¶ | |||
| be obtained from the IETF Secretariat. | be obtained from the IETF Secretariat. | |||
| The IETF invites any interested party to bring to its attention any | The IETF invites any interested party to bring to its attention any | |||
| copyrights, patents or patent applications, or other proprietary | copyrights, patents or patent applications, or other proprietary | |||
| rights which may cover technology that may be required to practice | rights which may cover technology that may be required to practice | |||
| this standard. Please address the information to the IETF Executive | this standard. Please address the information to the IETF Executive | |||
| Director. | Director. | |||
| Full Copyright Statement | Full Copyright Statement | |||
| Copyright (C) The Internet Society (2003). All Rights Reserved. | Copyright (C) The Internet Society (2004). All Rights Reserved. | |||
| This document and translations of it may be copied and furnished to | This document and translations of it may be copied and furnished to | |||
| others, and derivative works that comment on or otherwise explain it | others, and derivative works that comment on or otherwise explain it | |||
| or assist in its implementation may be prepared, copied, published | or assist in its implementation may be prepared, copied, published | |||
| and distributed, in whole or in part, without restriction of any | and distributed, in whole or in part, without restriction of any | |||
| kind, provided that the above copyright notice and this paragraph are | kind, provided that the above copyright notice and this paragraph are | |||
| included on all such copies and derivative works. However, this | included on all such copies and derivative works. However, this | |||
| document itself may not be modified in any way, such as by removing | document itself may not be modified in any way, such as by removing | |||
| the copyright notice or references to the Internet Society or other | the copyright notice or references to the Internet Society or other | |||
| Internet organizations, except as needed for the purpose of | Internet organizations, except as needed for the purpose of | |||
| skipping to change at page 32, line 7 ¶ | skipping to change at page 31, line 7 ¶ | |||
| The limited permissions granted above are perpetual and will not be | The limited permissions granted above are perpetual and will not be | |||
| revoked by the Internet Society or its successors or assignees. | revoked by the Internet Society or its successors or assignees. | |||
| This document and the information contained herein is provided on an | This document and the information contained herein is provided on an | |||
| "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING | "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING | |||
| TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING | TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING | |||
| BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION | BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION | |||
| HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF | HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF | |||
| MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |||
| Acknowledgement | Acknowledgment | |||
| Funding for the RFC Editor function is currently provided by the | Funding for the RFC Editor function is currently provided by the | |||
| Internet Society. | Internet Society. | |||
| End of changes. 51 change blocks. | ||||
| 70 lines changed or deleted | 44 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||