idnits 2.17.1 draft-mealling-uuid-urn-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** Looks like you're using RFC 2026 boilerplate. This must be updated to follow RFC 3978/3979, as updated by RFC 4748. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- == No 'Intended status' indicated for this document; assuming Proposed Standard Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** The abstract seems to contain references ([2], [1]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 387: '...e clock sequence MUST be originally (i...' RFC 2119 keyword, line 391: '...he initial value MUST NOT be correlate...' RFC 2119 keyword, line 501: '...nterval, the UUID service MUST either:...' RFC 2119 keyword, line 593: '... same namespace MUST be equal...' Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the RFC 3978 Section 5.4 Copyright Line does not match the current year == Line 287 has weird spacing: '...version uns...' == Line 291 has weird spacing: '...nd_rese unsig...' == Line 1171 has weird spacing: '...ed long unsi...' == Line 1172 has weird spacing: '...d short unsig...' == Line 1173 has weird spacing: '...ed char unsi...' == (1 more instance...) -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (October 3, 2003) is 7504 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Missing Reference: '16' is mentioned on line 1291, but not defined == Missing Reference: '0' is mentioned on line 1217, but not defined == Missing Reference: '257' is mentioned on line 1297, but not defined == Unused Reference: '4' is defined on line 786, but no explicit reference was found in the text -- Possible downref: Non-RFC (?) normative reference: ref. '1' -- Possible downref: Non-RFC (?) normative reference: ref. '2' ** Downref: Normative reference to an Informational RFC: RFC 1321 (ref. '3') ** Obsolete normative reference: RFC 2141 (ref. '4') (Obsoleted by RFC 8141) -- Possible downref: Non-RFC (?) normative reference: ref. '5' -- Possible downref: Non-RFC (?) normative reference: ref. '6' Summary: 6 errors (**), 0 flaws (~~), 12 warnings (==), 7 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group P. Leach 3 Internet-Draft Microsoft 4 Expires: April 2, 2004 M. Mealling 5 VeriSign, Inc. 6 R. Salz 7 DataPower Technology, Inc. 8 October 3, 2003 10 A UUID URN Namespace 11 draft-mealling-uuid-urn-01.txt 13 Status of this Memo 15 This document is an Internet-Draft and is in full conformance with 16 all provisions of Section 10 of RFC2026. 18 Internet-Drafts are working documents of the Internet Engineering 19 Task Force (IETF), its areas, and its working groups. Note that other 20 groups may also distribute working documents as Internet-Drafts. 22 Internet-Drafts are draft documents valid for a maximum of six months 23 and may be updated, replaced, or obsoleted by other documents at any 24 time. It is inappropriate to use Internet-Drafts as reference 25 material or to cite them other than as "work in progress." 27 The list of current Internet-Drafts can be accessed at http:// 28 www.ietf.org/ietf/1id-abstracts.txt. 30 The list of Internet-Draft Shadow Directories can be accessed at 31 http://www.ietf.org/shadow.html. 33 This Internet-Draft will expire on April 2, 2004. 35 Copyright Notice 37 Copyright (C) The Internet Society (2003). All Rights Reserved. 39 Abstract 41 This specification defines a Uniform Resource Name namespace for 42 UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally 43 Unique IDentifier). A UUID is 128 bits long, and can provide a 44 guarantee of uniqueness across space and time. UUIDs were originally 45 used in the Network Computing System (NCS) [1] and later in the Open 46 Software Foundation's (OSF) Distributed Computing Environment [2]. 48 This specification is derived from the latter specification with the 49 kind permission of the OSF (now known as The Open Group). Earlier 50 versions of this document never left draft stage; this document 51 incorporates that information here. 53 Table of Contents 55 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 56 2. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . 3 57 3. Namespace Registration Template . . . . . . . . . . . . . . 3 58 4. Specification . . . . . . . . . . . . . . . . . . . . . . . 6 59 4.1 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 60 4.1.1 Variant . . . . . . . . . . . . . . . . . . . . . . . . . . 6 61 4.1.2 Layout and byte order . . . . . . . . . . . . . . . . . . . 6 62 4.1.3 Version . . . . . . . . . . . . . . . . . . . . . . . . . . 8 63 4.1.4 Timestamp . . . . . . . . . . . . . . . . . . . . . . . . . 8 64 4.1.5 Clock sequence . . . . . . . . . . . . . . . . . . . . . . . 8 65 4.1.6 Node . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 66 4.1.7 Nil UUID . . . . . . . . . . . . . . . . . . . . . . . . . . 10 67 4.2 Algorithms for creating a time-based UUID . . . . . . . . . 10 68 4.2.1 Basic algorithm . . . . . . . . . . . . . . . . . . . . . . 10 69 4.2.2 Generation details . . . . . . . . . . . . . . . . . . . . . 12 70 4.3 Algorithm for creating a name-based UUID . . . . . . . . . . 13 71 4.4 Algorithms for creating a UUID from truly random or 72 pseudo-random numbers . . . . . . . . . . . . . . . . . . . 14 73 4.5 Node IDs that do not identify the host . . . . . . . . . . . 15 74 5. Community Considerations . . . . . . . . . . . . . . . . . . 16 75 6. Security Considerations . . . . . . . . . . . . . . . . . . 17 76 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . 17 77 Normative References . . . . . . . . . . . . . . . . . . . . 17 78 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 18 79 A. Appendix A - Sample Implementation . . . . . . . . . . . . . 18 80 B. Appendix B - Sample output of utest . . . . . . . . . . . . 29 81 C. Appendix C - Some name space IDs . . . . . . . . . . . . . . 29 82 Intellectual Property and Copyright Statements . . . . . . . 31 84 1. Introduction 86 This specification defines a Uniform Resource Name namespace for 87 UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally 88 Unique IDentifier). A UUID is 128 bits long, and requires no central 89 registration process. 91 The information here is meant to be a concise guide for those wishing 92 to implement services using UUIDs as URNs. Nothing in this document 93 should be construed to mean that it supersedes the DCE standards that 94 defined UUIDs to begin with. 96 2. Motivation 98 One of the main reasons for using UUIDs is that no centralized 99 authority is required to administer them (although one format uses 100 IEEE 802.1 node identifiers, others do not). As a result, generation 101 on demand can be completely automated, and they can be used for a 102 wide variety of purposes. The UUID generation algorithm described 103 here supports very high allocation rates: 10 million per second per 104 machine if necessary, so that they could even be used as transaction 105 IDs. 107 UUIDs are of a fixed size (128-bits) which is reasonably small 108 relative to other alternatives. This lends itself well to sorting, 109 ordering, and hashing of all sorts, storing in databases, simple 110 allocation, and ease of programming in general. 112 Since UUIDs are unique and persistent, they make excellent Uniform 113 Resource Names. The unique ability to generate a new UUID without a 114 registration process allows for UUIDs to be one of the URNs with the 115 lowest minting cost. 117 3. Namespace Registration Template 119 Namespace ID: UUID 121 Registration Information: 122 Registration date: 2003-10-01 124 Declared registrant of the namespace: 125 JTC 1/SC6 (ASN.1 Rapporteur Group) 127 Declaration of syntactic structure: 128 A UUID is an identifier that is unique across both space and time, 129 with respect to the space of all UUIDs. Since a UUID is a fixed 130 size and contains a time field, it is possible for values to 131 rollover (around A.D. 3400, depending on the specific algorithm 132 used). A UUID can be used for multiple purposes, from tagging 133 objects with an extremely short lifetime, to reliably identifying 134 very persistent objects across a network. 136 The internal representation of a UUID is a specific sequence of 137 bits in memory, as described in Section 4. In order to accurately 138 represent a UUID as a URN, it is necessary to convert the bit 139 sequence to a string representation. 141 Each field is treated as an integer and has its value printed as a 142 zero-filled hexadecimal digit string with the most significant 143 digit first. The hexadecimal values a through f are output as 144 lower case characters, and are case insensitive on input. 146 The formal definition of the UUID string representation is 147 provided by the following extended BNF: 149 UUID = "-" "-" 150 "-" 151 152 "-" 153 time_low = 4* 154 time_mid = 2* 155 time_high_and_version = 2* 156 clock_seq_and_reserved = 157 clock_seq_low = 158 node = 6* 160 hexDigit = 161 "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 162 | "a" | "b" | "c" | "d" | "e" | "f" 163 | "A" | "B" | "C" | "D" | "E" | "F" 165 The following is an example of the string representation of a UUID 166 as a URN: 168 urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 170 Relevant ancillary documentation: 171 [2] 173 Identifier uniqueness considerations: 174 This document specifies three algorithms to generate UUIDs: the 175 first leverages the unique values of 802.1 MAC addresses to 176 guarantee uniqueness, the second another uses pseudo-random number 177 generators, and the third uses cryptographic hashing and 178 application-provided text strings. As a result, it is possible to 179 guarantee that UUIDs generated according to the mechanisms here 180 will be unique from all other UUIDs that have been or will be 181 assigned. 183 Identifier persistence considerations: 184 UUIDs are inherently very difficult to resolve in a global sense. 185 This, coupled with the fact that UUIDs are temporally unique 186 within their spatial context, ensures that UUIDs will remain as 187 persistent as possible. 189 Process of identifier assignment: 190 Generating a UUID does not require that it be a registration 191 authority be contacted. One algorithm requires a unique value over 192 space for each generator. This value is typically an IEEE 802 193 address, usually already available on network-connected hosts. The 194 address can be assigned from an address block obtained from the 195 IEEE registration authority. If no such address is available, or 196 privacy concerns make its use undesirable, Section 4.5 specifies 197 two alternatives; another approach is to use version 3 or version 198 4 UUIDs as defined below. 200 Process for identifier resolution: 201 Since UUIDs are not globally resolvable, this is not applicable. 203 Rules for Lexical Equivalence: 204 Consider each field of the UUID to be an unsigned integer as shown 205 in the table in section Section 4.1.2. Then, to compare a pair of 206 UUIDs, arithmetically compare the corresponding fields from each 207 UUID in order of significance and according to their data type. 208 Two UUIDs are equal if and only if all the corresponding fields 209 are equal. 211 As an implementation note, on many systems equality comparison can 212 be performed by doing the appropriate byte-order canonicalization, 213 and then treating the two UUIDs as 128-bit unsigned integers. 215 UUIDs as defined in this document can also be ordered 216 lexicographically. For a pair of UUIDs, the first one follows the 217 second if the most significant field in which the UUIDs differ is 218 greater for the first UUID. The second precedes the first if the 219 most significant field in which the UUIDs differ is greater for 220 the second UUID. 222 Conformance with URN Syntax: 223 The string representation of a UUID is fully compatible with the 224 URN syntax. When converting from an bit-oriented, in-memory 225 representation of a UUID into a URN, care must be taken to 226 strictly adhere to the byte order issues mentioned in the string 227 representation section. 229 Validation mechanism: 230 Apart from determining if the timestamp portion of the UUID is in 231 the future and therefore not yet assignable, there is no mechanism 232 for determining if a UUID is 'valid' in any real sense. 234 Scope: 235 UUIDs are global in scope. 237 4. Specification 239 4.1 Format 241 In its most general form, all that can be said of the UUID format is 242 that a UUID is 16 octets, and that some bits of the eight octet -- 243 the variant field specified below -- determine finer structure. 245 4.1.1 Variant 247 The variant field determines the layout of the UUID. That is, the 248 interpretation of all other bits in the UUID depends on the setting 249 of the bits in the variant field. As such, it could more accurately 250 be called a type field; we retain the original term for 251 compatibility. The variant field consists of a variable number of the 252 most significant bits of the eighth octet of the UUID. 254 The following table lists the contents of the variant field, where 255 the letter "x" indicates a "don't-care" value. 257 Msb0 Msb1 Msb2 Description 259 0 x x Reserved, NCS backward compatibility. 261 1 0 x The variant specified in this document. 263 1 1 0 Reserved, Microsoft Corporation backward 264 compatibility 266 1 1 1 Reserved for future definition. 268 Interoperability (in any form) with variants other than the one 269 defined here is not guaranteed. This is unlikely to be an issue in 270 practice. 272 4.1.2 Layout and byte order 273 To minimize confusion about bit assignments within octets, the UUID 274 record definition is defined only in terms of fields that are 275 integral numbers of octets. The fields are presented with the most 276 significant one first. 278 Field Data Type Octet Note 279 # 281 time_low unsigned 32 0-3 The low field of the 282 bit integer timestamp 284 time_mid unsigned 16 4-5 The middle field of the 285 bit integer timestamp 287 time_hi_and_version unsigned 16 6-7 The high field of the 288 bit integer timestamp multiplexed 289 with the version number 291 clock_seq_hi_and_rese unsigned 8 8 The high field of the 292 rved bit integer clock sequence 293 multiplexed with the 294 variant 296 clock_seq_low unsigned 8 9 The low field of the 297 bit integer clock sequence 299 node unsigned 48 10-15 The spatially unique 300 bit integer node identifier 302 In the absence of explicit application or presentation protocol 303 specification to the contrary, a UUID is encoded as a 128-bit object, 304 as follows: the fields are encoded as 16 octets, with the sizes and 305 order of the fields defined above, and with each field encoded with 306 the Most Significant Byte first (this is known as network byte 307 order). 309 0 1 2 3 310 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 311 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 312 | time_low | 313 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 314 | time_mid | time_hi_and_version | 315 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 316 |clk_seq_hi_res | clk_seq_low | node (0-1) | 317 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 318 | node (2-5) | 319 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 321 4.1.3 Version 323 The version number is in the most significant four bits of the time 324 stamp (time_hi_and_version). 326 The following table lists the currently-defined versions for this 327 UUID variant. 329 Msb0 Msb1 Msb2 Msb3 Version Description 331 0 0 0 1 1 The time-based version 332 specified in this document. 334 0 0 1 0 2 DCE Security version, with 335 embedded POSIX UIDs. 337 0 0 1 1 3 The name-based version 338 specified in this document. 340 0 1 0 0 4 The randomly or pseudo- 341 randomly generated version 342 specified in this document. 344 The version is more accurately a sub-type; again, we retain the term 345 for compatibility. 347 4.1.4 Timestamp 349 The timestamp is a 60-bit value. For UUID version 1, this is 350 represented by Coordinated Universal Time (UTC) as a count of 351 100-nanosecond intervals since 00:00:00.00, 15 October 1582 (the date 352 of Gregorian reform to the Christian calendar). 354 For systems that do not have UTC available, but do have the local 355 time, they may use that instead of UTC, as long as they do so 356 consistently throughout the system. This is not recommended however, 357 particularly since all that is needed to generate UTC from local time 358 is a time zone offset. 360 For UUID version 3, the timestamp is a 60-bit value constructed from 361 a name as described in Section 4.3. 363 For UUID version 4, it is a randomly or pseudo-randomly generated 364 60-bit value, as described in Section 4.4. 366 4.1.5 Clock sequence 368 For UUID version 1, the clock sequence is used to help avoid 369 duplicates that could arise when the clock is set backwards in time 370 or if the node ID changes. 372 If the clock is set backwards, or even might have been set backwards 373 (e.g., while the system was powered off), and the UUID generator can 374 not be sure that no UUIDs were generated with timestamps larger than 375 the value to which the clock was set, then the clock sequence has to 376 be changed. If the previous value of the clock sequence is known, it 377 can be just incremented; otherwise it should be set to a random or 378 high-quality pseudo random value. 380 Similarly, if the node ID changes (e.g. because a network card has 381 been moved between machines), setting the clock sequence to a random 382 number minimizes the probability of a duplicate due to slight 383 differences in the clock settings of the machines. (If the value of 384 clock sequence associated with the changed node ID were known, then 385 the clock sequence could just be incremented, but that is unlikely.) 387 The clock sequence MUST be originally (i.e., once in the lifetime of 388 a system) initialized to a random number to minimize the correlation 389 across systems. This provides maximum protection against node 390 identifiers that may move or switch from system to system rapidly. 391 The initial value MUST NOT be correlated to the node identifier. 393 For UUID version 3, it is a 14-bit value constructed from a name as 394 described in Section 4.3. 396 For UUID version 4, it is a randomly or pseudo-randomly generated 397 14-bit value as described in Section 4.4. 399 4.1.6 Node 401 For UUID version 1, the node field consists of the IEEE address, 402 usually the host address. For systems with multiple IEEE 802 403 addresses, any available address can be used. The lowest addressed 404 octet (octet number 10) contains the global/local bit and the 405 unicast/multicast bit, and is the first octet of the address 406 transmitted on an 802.3 LAN. 408 For systems with no IEEE address, a randomly or pseudo-randomly 409 generated value may be used; see Section 4.5. The multicast bit must 410 be set in such addresses, in order that they will never conflict with 411 addresses obtained from network cards. 413 For UUID version 3, the node field is a 48-bit value constructed from 414 a name as described in Section 4.3. 416 For UUID version 4, the node field is a randomly or pseudo-randomly 417 generated 48-bit value as described in Section 4.4. 419 4.1.7 Nil UUID 421 The nil UUID is special form of UUID that is specified to have all 422 128 bits set to zero. 424 4.2 Algorithms for creating a time-based UUID 426 Various aspects of the algorithm for creating a version 1 UUID are 427 discussed in the following sections. 429 4.2.1 Basic algorithm 431 The following algorithm is simple, correct, and inefficient: 433 o Obtain a system-wide global lock 435 o From a system-wide shared stable store (e.g., a file), read the 436 UUID generator state: the values of the time stamp, clock 437 sequence, and node ID used to generate the last UUID. 439 o Get the current time as a 60-bit count of 100-nanosecond intervals 440 since 00:00:00.00, 15 October 1582 442 o Get the current node ID 444 o If the state was unavailable (e.g., non-existent or corrupted), or 445 the saved node ID is different than the current node ID, generate 446 a random clock sequence value 448 o If the state was available, but the saved time stamp is later than 449 the current time stamp, increment the clock sequence value 451 o Save the state (current time stamp, clock sequence, and node ID) 452 back to the stable store 454 o Release the global lock 456 o Format a UUID from the current time stamp, clock sequence, and 457 node ID values according to the steps in Section 4.2.2. 459 If UUIDs do not need to be frequently generated, the above algorithm 460 may be perfectly adequate. For higher performance requirements, 461 however, issues with the basic algorithm include: 463 o Reading the state from stable storage each time is inefficient 464 o The resolution of the system clock may not be 100-nanoseconds 466 o Writing the state to stable storage each time is inefficient 468 o Sharing the state across process boundaries may be inefficient 470 Each of these issues can be addressed in a modular fashion by local 471 improvements in the functions that read and write the state and read 472 the clock. We address each of them in turn in the following sections. 474 4.2.1.1 Reading stable storage 476 The state only needs to be read from stable storage once at boot 477 time, if it is read into a system-wide shared volatile store (and 478 updated whenever the stable store is updated). 480 If an implementation does not have any stable store available, then 481 it can always say that the values were unavailable. This is the least 482 desirable implementation, because it will increase the frequency of 483 creation of new clock sequence numbers, which increases the 484 probability of duplicates. 486 If the node ID can never change (e.g., the net card is inseparable 487 from the system), or if any change also reinitializes the clock 488 sequence to a random value, then instead of keeping it in stable 489 store, the current node ID may be returned. 491 4.2.1.2 System clock resolution 493 The time stamp is generated from the system time, whose resolution 494 may be less than the resolution of the UUID time stamp. 496 If UUIDs do not need to be frequently generated, the time stamp can 497 simply be the system time multiplied by the number of 100-nanosecond 498 intervals per system time interval. 500 If a system overruns the generator by requesting too many UUIDs 501 within a single system time interval, the UUID service MUST either: 502 return an error, or stall the UUID generator until the system clock 503 catches up. 505 A high resolution time stamp can be simulated by keeping a count of 506 how many UUIDs have been generated with the same value of the system 507 time, and using it to construction the low-order bits of the time 508 stamp. The count will range between zero and the number of 509 100-nanosecond intervals per system time interval. 511 Note: if the processors overrun the UUID generation frequently, 512 additional node identifiers can be allocated to the system, which 513 will permit higher speed allocation by making multiple UUIDs 514 potentially available for each time stamp value. 516 4.2.1.3 Writing stable storage 518 The state does not always need to be written to stable store every 519 time a UUID is generated. The timestamp in the stable store can be 520 periodically set to a value larger than any yet used in a UUID; as 521 long as the generated UUIDs have time stamps less than that value, 522 and the clock sequence and node ID remain unchanged, only the shared 523 volatile copy of the state needs to be updated. Furthermore, if the 524 time stamp value in stable store is in the future by less than the 525 typical time it takes the system to reboot, a crash will not cause a 526 reinitialization of the clock sequence. 528 4.2.1.4 Sharing state across processes 530 If it is too expensive to access shared state each time a UUID is 531 generated, then the system-wide generator can be implemented to 532 allocate a block of time stamps each time it is called, and a 533 per-process generator can allocate from that block until it is 534 exhausted. 536 4.2.2 Generation details 538 Version 1 UUIDs are generated according to the following algorithm: 540 o Determine the values for the UTC-based timestamp and clock 541 sequence to be used in the UUID, as described in Section 4.2.1. 543 o For the purposes of this algorithm, consider the timestamp to be a 544 60-bit unsigned integer and the clock sequence to be a 14-bit 545 unsigned integer. Sequentially number the bits in a field, 546 starting with zero for the least significant bit. 548 o Set the time_low field equal to the least significant 32 bits 549 (bits zero through 31) of the time stamp in the same order of 550 significance. 552 o Set the time_mid field equal to bits 32 through 47 from the time 553 stamp in the same order of significance. 555 o Set the 12 least significant bits (bits zero through 11) of the 556 time_hi_and_version field equal to bits 48 through 59 from the 557 time stamp in the same order of significance. 559 o Set the four most significant bits (bits 12 through 15) of the 560 time_hi_and_version field to the four-bit version number 561 corresponding to the UUID version being created, as shown in the 562 table above. 564 o Set the clock_seq_low field to the eight least significant bits 565 (bits zero through seven) of the clock sequence in the same order 566 of significance. 568 o Set the six least significant bits (bits zero through five) of the 569 clock_seq_hi_and_reserved field to the six most significant bits 570 (bits eight through 13) of the clock sequence in the same order of 571 significance. 573 o Set the two most significant bits (bits six and seven) of the 574 clock_seq_hi_and_reserved to zero and one, respectively. 576 o Set the node field to the 48-bit IEEE address in the same order of 577 significance as the address. 579 4.3 Algorithm for creating a name-based UUID 581 The version 3 UUID is meant for generating UUIDs from "names" that 582 are drawn from, and unique within, some "name space." The concept of 583 name and name space should be broadly construed, and not limited to 584 textual names. For example, some name spaces are the domain name 585 system, URLs, ISO Object IDs (OIDs), X.500 Distinguished Names (DNs), 586 and reserved words in a programming language. The mechanisms or 587 conventions for allocating names from, and ensuring their uniqueness 588 within, their name spaces are beyond the scope of this specification. 590 The requirements for version 3 UUIDs are as follows: 592 o The UUIDs generated at different times from the same name in the 593 same namespace MUST be equal 595 o The UUIDs generated from two different names in the same namespace 596 should be different (with very high probability) 598 o The UUIDs generated from the same name in two different namespaces 599 should be different with (very high probability) 601 o If two UUIDs that were generated from names are equal, then they 602 were generated from the same name in the same namespace (with very 603 high probability). 605 The algorithm for generating the a UUID from a name and a name space 606 are as follows: 608 o Allocate a UUID to use as a "name space ID" for all UUIDs 609 generated from names in that name space; see Appendix C for some 610 pre-defined values 612 o Convert the name to a canonical sequence of octets (as defined by 613 the standards or conventions of its name space); put the name 614 space ID in network byte order 616 o Compute the MD5 [3] hash of the name space ID concatenated with 617 the name 619 o Set octets zero through three of the time_low field to octets zero 620 through three of the MD5 hash 622 o Set octets zero and one of the time_mid field to octets four and 623 five of the MD5 hash 625 o Set octets zero and one of the time_hi_and_version field to octets 626 six and seven of the MD5 hash 628 o Set the four most significant bits (bits 12 through 15) of the 629 time_hi_and_version field to the four-bit version number from 630 Section 4.1.3. 632 o Set the clock_seq_hi_and_reserved field to octet eight of the MD5 633 hash 635 o Set the two most significant bits (bits 6 and 7) of the 636 clock_seq_hi_and_reserved to zero and one, respectively. 638 o Set the clock_seq_low field to octet nine of the MD5 hash 640 o Set octets zero through five of the node field to octets then 641 through fifteen of the MD5 hash 643 o Convert the resulting UUID to local byte order. 645 4.4 Algorithms for creating a UUID from truly random or pseudo-random 646 numbers 648 The version 4 UUID is meant for generating UUIDs from truly-random or 649 pseudo-random numbers. 651 The algorithm is as follows: 653 o Set the two most significant bits (bits six and seven) of the 654 clock_seq_hi_and_reserved to zero and one, respectively. 656 o Set the four most significant bits (bits 12 through 15) of the 657 time_hi_and_version field to the four-bit version number from 658 Section 4.1.3. 660 o Set all the other bits to randomly (or pseudo-randomly) chosen 661 values. 663 See Section 4.5 for a discussion on random numbers. 665 4.5 Node IDs that do not identify the host 667 This section describes how to generate a version 1 UUID if an IEEE 668 802 address is not available, or its use is not desired. 670 One approach is to contact the IEEE and get a separate block of 671 addresses. At the time of writing, the application could be found at 672 [6], and the cost was US$550. 674 A better solution is to obtain a 47-bit cryptographic quality random 675 number, and use it as the low 47 bits of the node ID, with the most 676 significant bit of the first octet of the node ID set to one. This 677 bit is the unicast/multicast bit, which will never be set in IEEE 802 678 addresses obtained from network cards; hence, there can never be a 679 conflict between UUIDs generated by machines with and without network 680 cards. 682 If a system does not have the capability to generate cryptographic 683 quality random numbers, then in most systems there are usually a 684 fairly large number of sources of randomness available from which one 685 can be generated. Such sources are system specific, but often 686 include: 688 o the percent of memory in use 690 o the size of main memory in bytes 692 o the amount of free main memory in bytes 694 o the size of the paging or swap file in bytes 696 o free bytes of paging or swap file 698 o the total size of user virtual address space in bytes 700 o the total available user address space bytes 702 o the size of boot disk drive in bytes 703 o the free disk space on boot drive in bytes 705 o the current time 707 o the amount of time since the system booted 709 o the individual sizes of files in various system directories 711 o the creation, last read, and modification times of files in 712 various system directories 714 o the utilization factors of various system resources (heap, etc.) 716 o current mouse cursor position 718 o current caret position 720 o current number of running processes, threads 722 o handles or IDs of the desktop window and the active window 724 o the value of stack pointer of the caller 726 o the process and thread ID of caller 728 o various processor architecture specific performance counters 729 (instructions executed, cache misses, TLB misses) 731 In addition, items such as the computer's name and the name of the 732 operating system, while not strictly speaking random, will help 733 differentiate the results from those obtained by other systems. 735 The exact algorithm to generate a node ID using these data is system 736 specific, because both the data available and the functions to obtain 737 them are often very system specific. A generic approach, however is 738 to accumulate as many sources as possible into a buffer, and use a 739 message digest such as MD5 [3], take an arbitrary six bytes from the 740 hash value, and set the multicast bit as described above. 742 Other hash functions, such as SHA-1 [5], can also be used. The only 743 requirement is that the result be suitably random in the sense that 744 the outputs from a set uniformly distributed inputs are themselves 745 uniformly distributed, and that a single bit change in the input can 746 be expected to cause half of the output bits to change. 748 5. Community Considerations 750 The use of UUIDs is extremely pervasive in computing. They comprise 751 the core identifier infrastructure for many operating systems 752 (Microsoft Windows) and applications (the Mozilla browser) and in 753 many cases, become exposed to the web in many non-standard ways. This 754 specification attempts to standardize that practice as openly as 755 possible and in a way that attempts to benefit the entire Internet. 757 6. Security Considerations 759 Do not assume that UUIDs are hard to guess; they should not be used 760 as capabilities, for example. 762 Do not assume that it is easy to determine if a UUID has been 763 slightly transposed in order to redirect a reference to another 764 object. Humans do not have the ability to easily check the integrity 765 of a UUID by simply glancing at it. 767 7. Acknowledgments 769 This document draws heavily on the OSF DCE specification for UUIDs. 770 Ted Ts'o provided helpful comments, especially on the byte ordering 771 section which we mostly plagiarized from a proposed wording he 772 supplied (all errors in that section are our responsibility, 773 however). 775 Normative References 777 [1] Zahn, L., Dineen, T. and P. Leach, "Network Computing 778 Architecture", ISBN 0-13-611674-4, January 1990. 780 [2] "DCE: Remote Procedure Call", Open Group CAE Specification C309, 781 ISBN 1-85912-041-5, August 1994. 783 [3] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 784 1992. 786 [4] Moats, R., "URN Syntax", RFC 2141, May 1997. 788 [5] National Institute of Standards and Technology, "Secure Hash 789 Standard", FIPS PUB 180-1, April 1995, . 792 [6] 794 Authors' Addresses 796 Paul J. Leach 797 Microsoft 798 1 Microsoft Way 799 Redmond, WA 98052 800 US 802 Phone: +1 425-882-8080 803 EMail: paulle@microsoft.com 805 Michael Mealling 806 VeriSign, Inc. 807 21345 Ridgetop Circle 808 Dulles, VA 21345 809 US 811 Phone: +1 678-581-9656 812 URI: http://www.verisignlabs.com 814 Rich Salz 815 DataPower Technology, Inc. 816 1 Alewife Center 817 Cambridge, MA 02142 818 US 820 Phone: +1 617-864-0455 821 EMail: rsalz@datapower.com 822 URI: http://www.datapower.com 824 Appendix A. Appendix A - Sample Implementation 826 This implementation consists of 5 files: uuid.h, uuid.c, sysdep.h, 827 sysdep.c and utest.c. The uuid.* files are the system independent 828 implementation of the UUID generation algorithms described above, 829 with all the optimizations described above except efficient state 830 sharing across processes included. The code has been tested on Linux 831 (Red Hat 4.0) with GCC (2.7.2), and Windows NT 4.0 with VC++ 5.0. The 832 code assumes 64-bit integer support, which makes it a lot clearer. 834 All the following source files should be considered to have the 835 following copyright notice included: 837 copyrt.h 839 /* 840 ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. 841 ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & 842 ** Digital Equipment Corporation, Maynard, Mass. 843 ** Copyright (c) 1998 Microsoft. 844 ** To anyone who acknowledges that this file is provided "AS IS" 845 ** without any express or implied warranty: permission to use, copy, 846 ** modify, and distribute this file for any purpose is hereby 847 ** granted without fee, provided that the above copyright notices and 848 ** this notice appears in all source code copies, and that none of 849 ** the names of Open Software Foundation, Inc., Hewlett-Packard 850 ** Company, or Digital Equipment Corporation be used in advertising 851 ** or publicity pertaining to distribution of the software without 852 ** specific, written prior permission. Neither Open Software 853 ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital 854 ** Equipment Corporation makes any representations about the 855 suitability 856 ** of this software for any purpose. 857 */ 859 uuid.h 861 #include "copyrt.h" 862 #undef uuid_t 863 typedef struct { 864 unsigned32 time_low; 865 unsigned16 time_mid; 866 unsigned16 time_hi_and_version; 867 unsigned8 clock_seq_hi_and_reserved; 868 unsigned8 clock_seq_low; 869 byte node[6]; 870 } uuid_t; 872 /* uuid_create -- generate a UUID */ 873 int uuid_create(uuid_t * uuid); 875 /* uuid_create_from_name -- create a UUID using a "name" 876 from a "name space" */ 877 void uuid_create_from_name( 878 uuid_t *uuid, /* resulting UUID */ 879 uuid_t nsid, /* UUID of the namespace */ 880 void *name, /* the name from which to generate a UUID 881 */ 882 int namelen /* the length of the name */ 883 ); 885 /* uuid_compare -- Compare two UUID's "lexically" and return 886 -1 u1 is lexically before u2 887 0 u1 is equal to u2 888 1 u1 is lexically after u2 890 Note that lexical ordering is not temporal ordering! 891 */ 892 int uuid_compare(uuid_t *u1, uuid_t *u2); 894 uuid.c 896 #include "copyrt.h" 897 #include 898 #include 899 #include 900 #include 901 #include "sysdep.h" 902 #include "uuid.h" 904 /* various forward declarations */ 905 static int read_state(unsigned16 *clockseq, uuid_time_t *timestamp, 906 uuid_node_t *node); 907 static void write_state(unsigned16 clockseq, uuid_time_t timestamp, 908 uuid_node_t node); 909 static void format_uuid_v1(uuid_t *uuid, unsigned16 clockseq, 910 uuid_time_t timestamp, uuid_node_t node); 911 static void format_uuid_v3(uuid_t *uuid, unsigned char hash[16]); 912 static void get_current_time(uuid_time_t *timestamp); 913 static unsigned16 true_random(void); 915 /* uuid_create -- generator a UUID */ 916 int uuid_create(uuid_t *uuid) 917 { 918 uuid_time_t timestamp, last_time; 919 unsigned16 clockseq; 920 uuid_node_t node; 921 uuid_node_t last_node; 922 int f; 924 /* acquire system-wide lock so we're alone */ 925 LOCK; 927 /* get time, node ID, saved state from non-volatile storage */ 928 get_current_time(×tamp); 929 get_ieee_node_identifier(&node); 930 f = read_state(&clockseq, &last_time, &last_node); 932 /* if no NV state, or if clock went backwards, or node ID 933 changed 934 (e.g., new network card) change clockseq */ 935 if (!f || memcmp(&node, &last_node, sizeof node)) 936 clockseq = true_random(); 937 else if (timestamp < last_time) 938 clockseq++; 940 /* save the state for next time */ 941 write_state(clockseq, timestamp, node); 943 UNLOCK; 945 /* stuff fields into the UUID */ 946 format_uuid_v1(uuid, clockseq, timestamp, node); 947 return 1; 948 } 950 /* format_uuid_v1 -- make a UUID from the timestamp, clockseq, 951 and node ID */ 952 void format_uuid_v1(uuid_t* uuid, unsigned16 clock_seq, 953 uuid_time_t timestamp, uuid_node_t node) 954 { 955 /* Construct a version 1 uuid with the information we've gathered 956 plus a few constants. */ 957 uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF); 958 uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF); 959 uuid->time_hi_and_version = 960 (unsigned short)((timestamp >> 48) & 0x0FFF); 961 uuid->time_hi_and_version |= (1 << 12); 962 uuid->clock_seq_low = clock_seq & 0xFF; 963 uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8; 964 uuid->clock_seq_hi_and_reserved |= 0x80; 965 memcpy(&uuid->node, &node, sizeof uuid->node); 966 } 968 /* data type for UUID generator persistent state */ 969 typedef struct { 970 uuid_time_t ts; /* saved timestamp */ 971 uuid_node_t node; /* saved node ID */ 972 unsigned16 cs; /* saved clock sequence */ 973 } uuid_state; 975 static uuid_state st; 977 /* read_state -- read UUID generator state from non-volatile store */ 978 int read_state(unsigned16 *clockseq, uuid_time_t *timestamp, 979 uuid_node_t *node) 980 { 981 static int inited = 0; 982 FILE *fp; 984 /* only need to read state once per boot */ 985 if (!inited) { 986 fp = fopen("state", "rb"); 987 if (fp == NULL) 988 return 0; 989 fread(&st, sizeof st, 1, fp); 990 fclose(fp); 991 inited = 1; 992 } 993 *clockseq = st.cs; 994 *timestamp = st.ts; 995 *node = st.node; 996 return 1; 997 } 999 /* write_state -- save UUID generator state back to non-volatile 1000 storage */ 1001 void write_state(unsigned16 clockseq, uuid_time_t timestamp, 1002 uuid_node_t node) 1003 { 1004 static int inited = 0; 1005 static uuid_time_t next_save; 1006 FILE* fp; 1008 if (!inited) { 1009 next_save = timestamp; 1010 inited = 1; 1011 } 1013 /* always save state to volatile shared state */ 1014 st.cs = clockseq; 1015 st.ts = timestamp; 1016 st.node = node; 1017 if (timestamp >= next_save) { 1018 fp = fopen("state", "wb"); 1019 fwrite(&st, sizeof st, 1, fp); 1020 fclose(fp); 1021 /* schedule next save for 10 seconds from now */ 1022 next_save = timestamp + (10 * 10 * 1000 * 1000); 1023 } 1024 } 1026 /* get-current_time -- get time as 60-bit 100ns ticks since UUID 1027 epoch. 1028 Compensate for the fact that real clock resolution is 1029 less than 100ns. */ 1030 void get_current_time(uuid_time_t *timestamp) 1031 { 1032 static int inited = 0; 1033 static uuid_time_t time_last; 1034 static unsigned16 uuids_this_tick; 1035 uuid_time_t time_now; 1036 if (!inited) { 1037 get_system_time(&time_now); 1038 uuids_this_tick = UUIDS_PER_TICK; 1039 inited = 1; 1040 } 1042 for ( ; ; ) { 1043 get_system_time(&time_now); 1045 /* if clock reading changed since last UUID generated, */ 1046 if (time_last != time_now) { 1047 /* reset count of uuids gen'd with this clock reading */ 1048 uuids_this_tick = 0; 1049 break; 1050 } 1051 if (uuids_this_tick < UUIDS_PER_TICK) { 1052 uuids_this_tick++; 1053 break; 1054 } 1055 /* going too fast for our clock; spin */ 1056 } 1057 /* add the count of uuids to low order bits of the clock reading 1058 */ 1059 *timestamp = time_now + uuids_this_tick; 1060 } 1062 /* true_random -- generate a crypto-quality random number. 1063 **This sample doesn't do that.** */ 1064 static unsigned16 true_random(void) 1065 { 1066 static int inited = 0; 1067 uuid_time_t time_now; 1069 if (!inited) { 1070 get_system_time(&time_now); 1071 time_now = time_now / UUIDS_PER_TICK; 1072 srand((unsigned int)(((time_now >> 32) ^ time_now) & 1073 0xffffffff)); 1074 inited = 1; 1075 } 1077 return rand(); 1078 } 1080 /* uuid_create_from_name -- create a UUID using a "name" from a "name 1081 space" */ 1082 void uuid_create_from_name(uuid_t *uuid, uuid_t nsid, void *name, 1083 int namelen) 1084 { 1085 MD5_CTX c; 1086 unsigned char hash[16]; 1087 uuid_t net_nsid; 1089 /* put name space ID in network byte order so it hashes the same 1090 no matter what endian machine we're on */ 1091 net_nsid = nsid; 1092 htonl(net_nsid.time_low); 1093 htons(net_nsid.time_mid); 1094 htons(net_nsid.time_hi_and_version); 1096 MD5Init(&c); 1097 MD5Update(&c, &net_nsid, sizeof net_nsid); 1098 MD5Update(&c, name, namelen); 1099 MD5Final(hash, &c); 1101 /* the hash is in network byte order at this point */ 1102 format_uuid_v3(uuid, hash); 1103 } 1105 /* format_uuid_v3 -- make a UUID from a (pseudo)random 128-bit number 1106 */ 1107 void format_uuid_v3(uuid_t *uuid, unsigned char hash[16]) 1108 { 1109 /* convert UUID to local byte order */ 1110 memcpy(uuid, hash, sizeof *uuid); 1111 ntohl(uuid->time_low); 1112 ntohs(uuid->time_mid); 1113 ntohs(uuid->time_hi_and_version); 1115 /* put in the variant and version bits */ 1116 uuid->time_hi_and_version &= 0x0FFF; 1117 uuid->time_hi_and_version |= (3 << 12); 1118 uuid->clock_seq_hi_and_reserved &= 0x3F; 1119 uuid->clock_seq_hi_and_reserved |= 0x80; 1120 } 1122 /* uuid_compare -- Compare two UUID's "lexically" and return */ 1123 #define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1; 1124 int uuid_compare(uuid_t *u1, uuid_t *u2) 1125 { 1126 int i; 1128 CHECK(u1->time_low, u2->time_low); 1129 CHECK(u1->time_mid, u2->time_mid); 1130 CHECK(u1->time_hi_and_version, u2->time_hi_and_version); 1131 CHECK(u1->clock_seq_hi_and_reserved, 1132 u2->clock_seq_hi_and_reserved); 1133 CHECK(u1->clock_seq_low, u2->clock_seq_low) 1134 for (i = 0; i < 6; i++) { 1135 if (u1->node[i] < u2->node[i]) 1136 return -1; 1137 if (u1->node[i] > u2->node[i]) 1138 return 1; 1139 } 1140 return 0; 1141 } 1142 #undef CHECK 1144 sysdep.h 1146 #include "copyrt.h" 1147 /* remove the following define if you aren't running WIN32 */ 1148 #define WININC 0 1150 #ifdef WININC 1151 #include 1152 #else 1153 #include 1154 #include 1155 #include 1156 #endif 1158 #include "global.h" 1159 /* change to point to where MD5 .h's live; RFC 1321 has sample 1160 implementation */ 1161 #include "md5.h" 1163 /* set the following to the number of 100ns ticks of the actual 1164 resolution of your system's clock */ 1165 #define UUIDS_PER_TICK 1024 1167 /* Set the following to a calls to get and release a global lock */ 1168 #define LOCK 1169 #define UNLOCK 1171 typedef unsigned long unsigned32; 1172 typedef unsigned short unsigned16; 1173 typedef unsigned char unsigned8; 1174 typedef unsigned char byte; 1176 /* Set this to what your compiler uses for 64-bit data type */ 1177 #ifdef WININC 1178 #define unsigned64_t unsigned __int64 1179 #define I64(C) C 1180 #else 1181 #define unsigned64_t unsigned long long 1182 #define I64(C) C##LL 1183 #endif 1185 typedef unsigned64_t uuid_time_t; 1186 typedef struct { 1187 char nodeID[6]; 1188 } uuid_node_t; 1190 void get_ieee_node_identifier(uuid_node_t *node); 1191 void get_system_time(uuid_time_t *uuid_time); 1192 void get_random_info(char seed[16]); 1194 sysdep.c 1196 #include "copyrt.h" 1197 #include 1198 #include "sysdep.h" 1200 /* system dependent call to get IEEE node ID. 1201 This sample implementation generates a random node ID. */ 1202 void get_ieee_node_identifier(uuid_node_t *node) 1203 { 1204 static inited = 0; 1205 static uuid_node_t saved_node; 1206 char seed[16]; 1207 FILE *fp; 1209 if (!inited) { 1210 fp = fopen("nodeid", "rb"); 1211 if (fp) { 1212 fread(&saved_node, sizeof saved_node, 1, fp); 1213 fclose(fp); 1214 } 1215 else { 1216 get_random_info(seed); 1217 seed[0] |= 0x80; 1218 memcpy(&saved_node, seed, sizeof saved_node); 1219 fp = fopen("nodeid", "wb"); 1220 if (fp) { 1221 fwrite(&saved_node, sizeof saved_node, 1, fp); 1222 fclose(fp); 1223 } 1224 } 1225 inited = 1; 1226 } 1228 *node = saved_node; 1229 } 1230 /* system dependent call to get the current system time. Returned as 1231 100ns ticks since UUID epoch, but resolution may be less than 1232 100ns. */ 1233 #ifdef _WINDOWS_ 1235 void get_system_time(uuid_time_t *uuid_time) 1236 { 1237 ULARGE_INTEGER time; 1239 /* NT keeps time in FILETIME format which is 100ns ticks since 1240 Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. 1241 The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) 1242 + 18 years and 5 leap days. */ 1243 GetSystemTimeAsFileTime((FILETIME *)&time); 1244 time.QuadPart += 1245 (unsigned __int64) (1000*1000*10) // seconds 1246 * (unsigned __int64) (60 * 60 * 24) // days 1247 * (unsigned __int64) (17+30+31+365*18+5); // # of days 1248 *uuid_time = time.QuadPart; 1249 } 1251 void get_random_info(char seed[16]) 1252 { 1253 MD5_CTX c; 1254 struct { 1255 MEMORYSTATUS m; 1256 SYSTEM_INFO s; 1257 FILETIME t; 1258 LARGE_INTEGER pc; 1259 DWORD tc; 1260 DWORD l; 1261 char hostname[MAX_COMPUTERNAME_LENGTH + 1]; 1262 } r; 1264 MD5Init(&c); 1265 GlobalMemoryStatus(&r.m); 1266 GetSystemInfo(&r.s); 1267 GetSystemTimeAsFileTime(&r.t); 1268 QueryPerformanceCounter(&r.pc); 1269 r.tc = GetTickCount(); 1270 r.l = MAX_COMPUTERNAME_LENGTH + 1; 1271 GetComputerName(r.hostname, &r.l); 1272 MD5Update(&c, &r, sizeof r); 1273 MD5Final(seed, &c); 1274 } 1276 #else 1278 void get_system_time(uuid_time_t *uuid_time) 1279 { 1280 struct timeval tp; 1282 gettimeofday(&tp, (struct timezone *)0); 1284 /* Offset between UUID formatted times and Unix formatted times. 1285 UUID UTC base time is October 15, 1582. 1286 Unix base time is January 1, 1970.*/ 1287 *uuid_time = (tp.tv_sec * 10000000) + (tp.tv_usec * 10) 1288 + I64(0x01B21DD213814000); 1289 } 1291 void get_random_info(char seed[16]) 1292 { 1293 MD5_CTX c; 1294 struct { 1295 struct sysinfo s; 1296 struct timeval t; 1297 char hostname[257]; 1298 } r; 1300 MD5Init(&c); 1301 sysinfo(&r.s); 1302 gettimeofday(&r.t, (struct timezone *)0); 1303 gethostname(r.hostname, 256); 1304 MD5Update(&c, &r, sizeof r); 1305 MD5Final(seed, &c); 1306 } 1308 #endif 1310 utest.c 1312 #include "copyrt.h" 1313 #include "sysdep.h" 1314 #include 1315 #include "uuid.h" 1317 uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ 1318 0x6ba7b810, 1319 0x9dad, 1320 0x11d1, 1321 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1322 }; 1324 /* puid -- print a UUID */ 1325 void puid(uuid_t u) 1326 { 1327 int i; 1329 printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid, 1330 u.time_hi_and_version, u.clock_seq_hi_and_reserved, 1331 u.clock_seq_low); 1332 for (i = 0; i < 6; i++) 1333 printf("%2.2x", u.node[i]); 1334 printf("\n"); 1335 } 1337 /* Simple driver for UUID generator */ 1338 void main(int argc, char **argv) 1339 { 1340 uuid_t u; 1341 int f; 1343 uuid_create(&u); 1344 printf("uuid_create(): "); puid(u); 1346 f = uuid_compare(&u, &u); 1347 printf("uuid_compare(u,u): %d\n", f); /* should be 0 */ 1348 f = uuid_compare(&u, &NameSpace_DNS); 1349 printf("uuid_compare(u, NameSpace_DNS): %d\n", f); /* s.b. 1 */ 1350 f = uuid_compare(&NameSpace_DNS, &u); 1351 printf("uuid_compare(NameSpace_DNS, u): %d\n", f); /* s.b. -1 */ 1352 uuid_create_from_name(&u, NameSpace_DNS, "www.widgets.com", 15); 1353 printf("uuid_create_from_name(): "); puid(u); 1354 } 1356 Appendix B. Appendix B - Sample output of utest 1358 uuid_create(): 7d444840-9dc0-11d1-b245-5ffdce74fad2 1359 uuid_compare(u,u): 0 1360 uuid_compare(u, NameSpace_DNS): 1 1361 uuid_compare(NameSpace_DNS, u): -1 1362 uuid_create_from_name(): e902893a-9d22-3c7e-a7b8-d6e313b71d9f 1364 Appendix C. Appendix C - Some name space IDs 1366 This appendix lists the name space IDs for some potentially 1367 interesting name spaces, as initialized C structures and in the 1368 string representation defined above. 1370 /* Name string is a fully-qualified domain name */ 1371 uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ 1372 0x6ba7b810, 1373 0x9dad, 1374 0x11d1, 1375 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1376 }; 1378 /* Name string is a URL */ 1379 uuid_t NameSpace_URL = { /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */ 1380 0x6ba7b811, 1381 0x9dad, 1382 0x11d1, 1383 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1384 }; 1386 /* Name string is an ISO OID */ 1387 uuid_t NameSpace_OID = { /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */ 1388 0x6ba7b812, 1389 0x9dad, 1390 0x11d1, 1391 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1392 }; 1394 /* Name string is an X.500 DN (in DER or a text output format) */ 1395 uuid_t NameSpace_X500 = { /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */ 1396 0x6ba7b814, 1397 0x9dad, 1398 0x11d1, 1399 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1400 }; 1402 Intellectual Property Statement 1404 The IETF takes no position regarding the validity or scope of any 1405 intellectual property or other rights that might be claimed to 1406 pertain to the implementation or use of the technology described in 1407 this document or the extent to which any license under such rights 1408 might or might not be available; neither does it represent that it 1409 has made any effort to identify any such rights. Information on the 1410 IETF's procedures with respect to rights in standards-track and 1411 standards-related documentation can be found in BCP-11. Copies of 1412 claims of rights made available for publication and any assurances of 1413 licenses to be made available, or the result of an attempt made to 1414 obtain a general license or permission for the use of such 1415 proprietary rights by implementors or users of this specification can 1416 be obtained from the IETF Secretariat. 1418 The IETF invites any interested party to bring to its attention any 1419 copyrights, patents or patent applications, or other proprietary 1420 rights which may cover technology that may be required to practice 1421 this standard. Please address the information to the IETF Executive 1422 Director. 1424 Full Copyright Statement 1426 Copyright (C) The Internet Society (2003). All Rights Reserved. 1428 This document and translations of it may be copied and furnished to 1429 others, and derivative works that comment on or otherwise explain it 1430 or assist in its implementation may be prepared, copied, published 1431 and distributed, in whole or in part, without restriction of any 1432 kind, provided that the above copyright notice and this paragraph are 1433 included on all such copies and derivative works. However, this 1434 document itself may not be modified in any way, such as by removing 1435 the copyright notice or references to the Internet Society or other 1436 Internet organizations, except as needed for the purpose of 1437 developing Internet standards in which case the procedures for 1438 copyrights defined in the Internet Standards process must be 1439 followed, or as required to translate it into languages other than 1440 English. 1442 The limited permissions granted above are perpetual and will not be 1443 revoked by the Internet Society or its successors or assignees. 1445 This document and the information contained herein is provided on an 1446 "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING 1447 TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 1448 BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION 1449 HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 1450 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 1452 Acknowledgement 1454 Funding for the RFC Editor function is currently provided by the 1455 Internet Society.