idnits 2.17.1 draft-mealling-uuid-urn-02.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.) ** There are 10 instances of too long lines in the document, the longest one being 6 characters in excess of 72. ** 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 377: '...e clock sequence MUST be originally (i...' RFC 2119 keyword, line 381: '...he initial value MUST NOT be correlate...' RFC 2119 keyword, line 479: '...nterval, the UUID service MUST either:...' RFC 2119 keyword, line 560: '... 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 276 has weird spacing: '...version uns...' == Line 280 has weird spacing: '...nd_rese unsig...' == Line 1090 has weird spacing: '...ed long unsi...' == Line 1091 has weird spacing: '...d short unsig...' == Line 1092 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 (January 28, 2004) is 7392 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 1211, but not defined == Missing Reference: '0' is mentioned on line 1135, but not defined == Missing Reference: '257' is mentioned on line 1217, but not defined == Unused Reference: '4' is defined on line 716, 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: 7 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: July 28, 2004 M. Mealling 5 VeriSign, Inc. 6 R. Salz 7 DataPower Technology, Inc. 8 January 28, 2004 10 A UUID URN Namespace 11 draft-mealling-uuid-urn-02.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 July 28, 2004. 35 Copyright Notice 37 Copyright (C) The Internet Society (2004). 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 . . . . . . . . . . . . . . . . . . . . . . . 5 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 . . . . . . . . . . . . . . . . . . . . . . . . . . 7 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 . . . . . . . . . . 12 71 4.4 Algorithms for creating a UUID from truly random or 72 pseudo-random numbers . . . . . . . . . . . . . . . . . . . 13 73 4.5 Node IDs that do not identify the host . . . . . . . . . . . 14 74 5. Community Considerations . . . . . . . . . . . . . . . . . . 15 75 6. Security Considerations . . . . . . . . . . . . . . . . . . 15 76 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . 16 77 Normative References . . . . . . . . . . . . . . . . . . . . 16 78 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 16 79 A. Appendix A - Sample Implementation . . . . . . . . . . . . . 17 80 B. Appendix B - Sample output of utest . . . . . . . . . . . . 28 81 C. Appendix C - Some name space IDs . . . . . . . . . . . . . . 28 82 Intellectual Property and Copyright Statements . . . . . . . 30 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 120 Registration Information: 121 Registration date: 2003-10-01 122 Declared registrant of the namespace: 123 JTC 1/SC6 (ASN.1 Rapporteur Group) 124 Declaration of syntactic structure: 125 A UUID is an identifier that is unique across both space and time, 126 with respect to the space of all UUIDs. Since a UUID is a fixed 127 size and contains a time field, it is possible for values to 128 rollover (around A.D. 3400, depending on the specific algorithm 129 used). A UUID can be used for multiple purposes, from tagging 130 objects with an extremely short lifetime, to reliably identifying 131 very persistent objects across a network. 133 The internal representation of a UUID is a specific sequence of 134 bits in memory, as described in Section 4. In order to accurately 135 represent a UUID as a URN, it is necessary to convert the bit 136 sequence to a string representation. 138 Each field is treated as an integer and has its value printed as a 139 zero-filled hexadecimal digit string with the most significant 140 digit first. The hexadecimal values a through f are output as 141 lower case characters, and are case insensitive on input. 143 The formal definition of the UUID string representation is 144 provided by the following extended BNF: 146 UUID = "-" "-" 147 "-" 148 149 "-" 150 time_low = 4* 151 time_mid = 2* 152 time_high_and_version = 2* 153 clock_seq_and_reserved = 154 clock_seq_low = 155 node = 6* 157 hexDigit = 158 "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 159 | "a" | "b" | "c" | "d" | "e" | "f" 160 | "A" | "B" | "C" | "D" | "E" | "F" 162 The following is an example of the string representation of a UUID 163 as a URN: 165 urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 167 Relevant ancillary documentation: 168 [2] 169 Identifier uniqueness considerations: 170 This document specifies three algorithms to generate UUIDs: the 171 first leverages the unique values of 802.1 MAC addresses to 172 guarantee uniqueness, the second another uses pseudo-random number 173 generators, and the third uses cryptographic hashing and 174 application-provided text strings. As a result, it is possible to 175 guarantee that UUIDs generated according to the mechanisms here 176 will be unique from all other UUIDs that have been or will be 177 assigned. 178 Identifier persistence considerations: 179 UUIDs are inherently very difficult to resolve in a global sense. 180 This, coupled with the fact that UUIDs are temporally unique 181 within their spatial context, ensures that UUIDs will remain as 182 persistent as possible. 183 Process of identifier assignment: 184 Generating a UUID does not require that it be a registration 185 authority be contacted. One algorithm requires a unique value over 186 space for each generator. This value is typically an IEEE 802 187 address, usually already available on network-connected hosts. The 188 address can be assigned from an address block obtained from the 189 IEEE registration authority. If no such address is available, or 190 privacy concerns make its use undesirable, Section 4.5 specifies 191 two alternatives; another approach is to use version 3 or version 192 4 UUIDs as defined below. 193 Process for identifier resolution: 194 Since UUIDs are not globally resolvable, this is not applicable. 195 Rules for Lexical Equivalence: 196 Consider each field of the UUID to be an unsigned integer as shown 197 in the table in section Section 4.1.2. Then, to compare a pair of 198 UUIDs, arithmetically compare the corresponding fields from each 199 UUID in order of significance and according to their data type. 200 Two UUIDs are equal if and only if all the corresponding fields 201 are equal. 203 As an implementation note, on many systems equality comparison can 204 be performed by doing the appropriate byte-order canonicalization, 205 and then treating the two UUIDs as 128-bit unsigned integers. 207 UUIDs as defined in this document can also be ordered 208 lexicographically. For a pair of UUIDs, the first one follows the 209 second if the most significant field in which the UUIDs differ is 210 greater for the first UUID. The second precedes the first if the 211 most significant field in which the UUIDs differ is greater for 212 the second UUID. 213 Conformance with URN Syntax: 214 The string representation of a UUID is fully compatible with the 215 URN syntax. When converting from an bit-oriented, in-memory 216 representation of a UUID into a URN, care must be taken to 217 strictly adhere to the byte order issues mentioned in the string 218 representation section. 219 Validation mechanism: 220 Apart from determining if the timestamp portion of the UUID is in 221 the future and therefore not yet assignable, there is no mechanism 222 for determining if a UUID is 'valid' in any real sense. 223 Scope: 224 UUIDs are global in scope. 226 4. Specification 227 4.1 Format 229 In its most general form, all that can be said of the UUID format is 230 that a UUID is 16 octets, and that some bits of the eight octet -- 231 the variant field specified below -- determine finer structure. 233 4.1.1 Variant 235 The variant field determines the layout of the UUID. That is, the 236 interpretation of all other bits in the UUID depends on the setting 237 of the bits in the variant field. As such, it could more accurately 238 be called a type field; we retain the original term for 239 compatibility. The variant field consists of a variable number of the 240 most significant bits of the eighth octet of the UUID. 242 The following table lists the contents of the variant field, where 243 the letter "x" indicates a "don't-care" value. 245 Msb0 Msb1 Msb2 Description 247 0 x x Reserved, NCS backward compatibility. 249 1 0 x The variant specified in this document. 251 1 1 0 Reserved, Microsoft Corporation backward 252 compatibility 254 1 1 1 Reserved for future definition. 256 Interoperability (in any form) with variants other than the one 257 defined here is not guaranteed. This is unlikely to be an issue in 258 practice. 260 4.1.2 Layout and byte order 262 To minimize confusion about bit assignments within octets, the UUID 263 record definition is defined only in terms of fields that are 264 integral numbers of octets. The fields are presented with the most 265 significant one first. 267 Field Data Type Octet Note 268 # 270 time_low unsigned 32 0-3 The low field of the 271 bit integer timestamp 273 time_mid unsigned 16 4-5 The middle field of the 274 bit integer timestamp 276 time_hi_and_version unsigned 16 6-7 The high field of the 277 bit integer timestamp multiplexed 278 with the version number 280 clock_seq_hi_and_rese unsigned 8 8 The high field of the 281 rved bit integer clock sequence 282 multiplexed with the 283 variant 285 clock_seq_low unsigned 8 9 The low field of the 286 bit integer clock sequence 288 node unsigned 48 10-15 The spatially unique 289 bit integer node identifier 291 In the absence of explicit application or presentation protocol 292 specification to the contrary, a UUID is encoded as a 128-bit object, 293 as follows: the fields are encoded as 16 octets, with the sizes and 294 order of the fields defined above, and with each field encoded with 295 the Most Significant Byte first (this is known as network byte 296 order). Note that the field names, particularly for multiplexed 297 fields, follow historical practice. 299 0 1 2 3 300 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 301 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 302 | time_low | 303 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 304 | time_mid | time_hi_and_version | 305 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 306 |clk_seq_hi_res | clk_seq_low | node (0-1) | 307 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 308 | node (2-5) | 309 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 311 4.1.3 Version 313 The version number is in the most significant four bits of the time 314 stamp (bits four through seven of the time_hi_and_version field). 316 The following table lists the currently-defined versions for this 317 UUID variant. 319 Msb0 Msb1 Msb2 Msb3 Version Description 321 0 0 0 1 1 The time-based version 322 specified in this document. 324 0 0 1 0 2 DCE Security version, with 325 embedded POSIX UIDs. 327 0 0 1 1 3 The name-based version 328 specified in this document. 330 0 1 0 0 4 The randomly or pseudo- 331 randomly generated version 332 specified in this document. 334 The version is more accurately a sub-type; again, we retain the term 335 for compatibility. 337 4.1.4 Timestamp 339 The timestamp is a 60-bit value. For UUID version 1, this is 340 represented by Coordinated Universal Time (UTC) as a count of 341 100-nanosecond intervals since 00:00:00.00, 15 October 1582 (the date 342 of Gregorian reform to the Christian calendar). 344 For systems that do not have UTC available, but do have the local 345 time, they may use that instead of UTC, as long as they do so 346 consistently throughout the system. This is not recommended however, 347 particularly since all that is needed to generate UTC from local time 348 is a time zone offset. 350 For UUID version 3, the timestamp is a 60-bit value constructed from 351 a name as described in Section 4.3. 353 For UUID version 4, it is a randomly or pseudo-randomly generated 354 60-bit value, as described in Section 4.4. 356 4.1.5 Clock sequence 358 For UUID version 1, the clock sequence is used to help avoid 359 duplicates that could arise when the clock is set backwards in time 360 or if the node ID changes. 362 If the clock is set backwards, or even might have been set backwards 363 (e.g., while the system was powered off), and the UUID generator can 364 not be sure that no UUIDs were generated with timestamps larger than 365 the value to which the clock was set, then the clock sequence has to 366 be changed. If the previous value of the clock sequence is known, it 367 can be just incremented; otherwise it should be set to a random or 368 high-quality pseudo random value. 370 Similarly, if the node ID changes (e.g. because a network card has 371 been moved between machines), setting the clock sequence to a random 372 number minimizes the probability of a duplicate due to slight 373 differences in the clock settings of the machines. (If the value of 374 clock sequence associated with the changed node ID were known, then 375 the clock sequence could just be incremented, but that is unlikely.) 377 The clock sequence MUST be originally (i.e., once in the lifetime of 378 a system) initialized to a random number to minimize the correlation 379 across systems. This provides maximum protection against node 380 identifiers that may move or switch from system to system rapidly. 381 The initial value MUST NOT be correlated to the node identifier. 383 For UUID version 3, it is a 14-bit value constructed from a name as 384 described in Section 4.3. 386 For UUID version 4, it is a randomly or pseudo-randomly generated 387 14-bit value as described in Section 4.4. 389 4.1.6 Node 391 For UUID version 1, the node field consists of an IEEE address, 392 usually the host address. For systems with multiple IEEE 802 393 addresses, any available address can be used. The lowest addressed 394 octet (octet number 10) contains the global/local bit and the 395 unicast/multicast bit, and is the first octet of the address 396 transmitted on an 802.3 LAN. 398 For systems with no IEEE address, a randomly or pseudo-randomly 399 generated value may be used; see Section 4.5. The multicast bit must 400 be set in such addresses, in order that they will never conflict with 401 addresses obtained from network cards. 403 For UUID version 3, the node field is a 48-bit value constructed from 404 a name as described in Section 4.3. 406 For UUID version 4, the node field is a randomly or pseudo-randomly 407 generated 48-bit value as described in Section 4.4. 409 4.1.7 Nil UUID 411 The nil UUID is special form of UUID that is specified to have all 412 128 bits set to zero. 414 4.2 Algorithms for creating a time-based UUID 416 Various aspects of the algorithm for creating a version 1 UUID are 417 discussed in the following sections. 419 4.2.1 Basic algorithm 421 The following algorithm is simple, correct, and inefficient: 422 o Obtain a system-wide global lock 423 o From a system-wide shared stable store (e.g., a file), read the 424 UUID generator state: the values of the time stamp, clock 425 sequence, and node ID used to generate the last UUID. 426 o Get the current time as a 60-bit count of 100-nanosecond intervals 427 since 00:00:00.00, 15 October 1582 428 o Get the current node ID 429 o If the state was unavailable (e.g., non-existent or corrupted), or 430 the saved node ID is different than the current node ID, generate 431 a random clock sequence value 432 o If the state was available, but the saved time stamp is later than 433 the current time stamp, increment the clock sequence value 434 o Save the state (current time stamp, clock sequence, and node ID) 435 back to the stable store 436 o Release the global lock 437 o Format a UUID from the current time stamp, clock sequence, and 438 node ID values according to the steps in Section 4.2.2. 440 If UUIDs do not need to be frequently generated, the above algorithm 441 may be perfectly adequate. For higher performance requirements, 442 however, issues with the basic algorithm include: 443 o Reading the state from stable storage each time is inefficient 444 o The resolution of the system clock may not be 100-nanoseconds 445 o Writing the state to stable storage each time is inefficient 446 o Sharing the state across process boundaries may be inefficient 448 Each of these issues can be addressed in a modular fashion by local 449 improvements in the functions that read and write the state and read 450 the clock. We address each of them in turn in the following sections. 452 4.2.1.1 Reading stable storage 454 The state only needs to be read from stable storage once at boot 455 time, if it is read into a system-wide shared volatile store (and 456 updated whenever the stable store is updated). 458 If an implementation does not have any stable store available, then 459 it can always say that the values were unavailable. This is the least 460 desirable implementation, because it will increase the frequency of 461 creation of new clock sequence numbers, which increases the 462 probability of duplicates. 464 If the node ID can never change (e.g., the net card is inseparable 465 from the system), or if any change also reinitializes the clock 466 sequence to a random value, then instead of keeping it in stable 467 store, the current node ID may be returned. 469 4.2.1.2 System clock resolution 471 The time stamp is generated from the system time, whose resolution 472 may be less than the resolution of the UUID time stamp. 474 If UUIDs do not need to be frequently generated, the time stamp can 475 simply be the system time multiplied by the number of 100-nanosecond 476 intervals per system time interval. 478 If a system overruns the generator by requesting too many UUIDs 479 within a single system time interval, the UUID service MUST either: 480 return an error, or stall the UUID generator until the system clock 481 catches up. 483 A high resolution time stamp can be simulated by keeping a count of 484 how many UUIDs have been generated with the same value of the system 485 time, and using it to construction the low-order bits of the time 486 stamp. The count will range between zero and the number of 487 100-nanosecond intervals per system time interval. 489 Note: if the processors overrun the UUID generation frequently, 490 additional node identifiers can be allocated to the system, which 491 will permit higher speed allocation by making multiple UUIDs 492 potentially available for each time stamp value. 494 4.2.1.3 Writing stable storage 496 The state does not always need to be written to stable store every 497 time a UUID is generated. The timestamp in the stable store can be 498 periodically set to a value larger than any yet used in a UUID; as 499 long as the generated UUIDs have time stamps less than that value, 500 and the clock sequence and node ID remain unchanged, only the shared 501 volatile copy of the state needs to be updated. Furthermore, if the 502 time stamp value in stable store is in the future by less than the 503 typical time it takes the system to reboot, a crash will not cause a 504 reinitialization of the clock sequence. 506 4.2.1.4 Sharing state across processes 508 If it is too expensive to access shared state each time a UUID is 509 generated, then the system-wide generator can be implemented to 510 allocate a block of time stamps each time it is called, and a 511 per-process generator can allocate from that block until it is 512 exhausted. 514 4.2.2 Generation details 516 Version 1 UUIDs are generated according to the following algorithm: 517 o Determine the values for the UTC-based timestamp and clock 518 sequence to be used in the UUID, as described in Section 4.2.1. 519 o For the purposes of this algorithm, consider the timestamp to be a 520 60-bit unsigned integer and the clock sequence to be a 14-bit 521 unsigned integer. Sequentially number the bits in a field, 522 starting with zero for the least significant bit. 523 o Set the time_low field equal to the least significant 32 bits 524 (bits zero through 31) of the time stamp in the same order of 525 significance. 526 o Set the time_mid field equal to bits 32 through 47 from the time 527 stamp in the same order of significance. 528 o Set the 12 least significant bits (bits zero through 11) of the 529 time_hi_and_version field equal to bits 48 through 59 from the 530 time stamp in the same order of significance. 531 o Set the four most significant bits (bits 12 through 15) of the 532 time_hi_and_version field to the four-bit version number 533 corresponding to the UUID version being created, as shown in the 534 table above. 535 o Set the clock_seq_low field to the eight least significant bits 536 (bits zero through seven) of the clock sequence in the same order 537 of significance. 538 o Set the six least significant bits (bits zero through five) of the 539 clock_seq_hi_and_reserved field to the six most significant bits 540 (bits eight through 13) of the clock sequence in the same order of 541 significance. 542 o Set the two most significant bits (bits six and seven) of the 543 clock_seq_hi_and_reserved to zero and one, respectively. 544 o Set the node field to the 48-bit IEEE address in the same order of 545 significance as the address. 547 4.3 Algorithm for creating a name-based UUID 549 The version 3 UUID is meant for generating UUIDs from "names" that 550 are drawn from, and unique within, some "name space." The concept of 551 name and name space should be broadly construed, and not limited to 552 textual names. For example, some name spaces are the domain name 553 system, URLs, ISO Object IDs (OIDs), X.500 Distinguished Names (DNs), 554 and reserved words in a programming language. The mechanisms or 555 conventions for allocating names from, and ensuring their uniqueness 556 within, their name spaces are beyond the scope of this specification. 558 The requirements for version 3 UUIDs are as follows: 559 o The UUIDs generated at different times from the same name in the 560 same namespace MUST be equal 561 o The UUIDs generated from two different names in the same namespace 562 should be different (with very high probability) 563 o The UUIDs generated from the same name in two different namespaces 564 should be different with (very high probability) 565 o If two UUIDs that were generated from names are equal, then they 566 were generated from the same name in the same namespace (with very 567 high probability). 569 The algorithm for generating the a UUID from a name and a name space 570 are as follows: 571 o Allocate a UUID to use as a "name space ID" for all UUIDs 572 generated from names in that name space; see Appendix C for some 573 pre-defined values 574 o Convert the name to a canonical sequence of octets (as defined by 575 the standards or conventions of its name space); put the name 576 space ID in network byte order 577 o Compute the MD5 [3] hash of the name space ID concatenated with 578 the name 579 o Set octets zero through three of the time_low field to octets zero 580 through three of the MD5 hash 581 o Set octets zero and one of the time_mid field to octets four and 582 five of the MD5 hash 583 o Set octets zero and one of the time_hi_and_version field to octets 584 six and seven of the MD5 hash 585 o Set the four most significant bits (bits 12 through 15) of the 586 time_hi_and_version field to the four-bit version number from 587 Section 4.1.3. 588 o Set the clock_seq_hi_and_reserved field to octet eight of the MD5 589 hash 590 o Set the two most significant bits (bits six and seven) of the 591 clock_seq_hi_and_reserved to zero and one, respectively. 592 o Set the clock_seq_low field to octet nine of the MD5 hash 593 o Set octets zero through five of the node field to octets then 594 through fifteen of the MD5 hash 595 o Convert the resulting UUID to local byte order. 597 4.4 Algorithms for creating a UUID from truly random or pseudo-random 598 numbers 600 The version 4 UUID is meant for generating UUIDs from truly-random or 601 pseudo-random numbers. 603 The algorithm is as follows: 604 o Set the two most significant bits (bits six and seven) of the 605 clock_seq_hi_and_reserved to zero and one, respectively. 606 o Set the four most significant bits (bits 12 through 15) of the 607 time_hi_and_version field to the four-bit version number from 608 Section 4.1.3. 609 o Set all the other bits to randomly (or pseudo-randomly) chosen 610 values. 612 See Section 4.5 for a discussion on random numbers. 614 4.5 Node IDs that do not identify the host 616 This section describes how to generate a version 1 UUID if an IEEE 617 802 address is not available, or its use is not desired. 619 One approach is to contact the IEEE and get a separate block of 620 addresses. At the time of writing, the application could be found at 621 [6], and the cost was US$550. 623 A better solution is to obtain a 47-bit cryptographic quality random 624 number, and use it as the low 47 bits of the node ID, with the most 625 significant bit of the first octet of the node ID set to one. This 626 bit is the unicast/multicast bit, which will never be set in IEEE 802 627 addresses obtained from network cards; hence, there can never be a 628 conflict between UUIDs generated by machines with and without network 629 cards. 631 If a system does not have the capability to generate cryptographic 632 quality random numbers, then in most systems there are usually a 633 fairly large number of sources of randomness available from which one 634 can be generated. Such sources are system specific, but often 635 include: 636 o the percent of memory in use 637 o the size of main memory in bytes 638 o the amount of free main memory in bytes 639 o the size of the paging or swap file in bytes 640 o free bytes of paging or swap file 641 o the total size of user virtual address space in bytes 642 o the total available user address space bytes 643 o the size of boot disk drive in bytes 644 o the free disk space on boot drive in bytes 645 o the current time 646 o the amount of time since the system booted 647 o the individual sizes of files in various system directories 648 o the creation, last read, and modification times of files in 649 various system directories 651 o the utilization factors of various system resources (heap, etc.) 652 o current mouse cursor position 653 o current caret position 654 o current number of running processes, threads 655 o handles or IDs of the desktop window and the active window 656 o the value of stack pointer of the caller 657 o the process and thread ID of caller 658 o various processor architecture specific performance counters 659 (instructions executed, cache misses, TLB misses) 661 In addition, items such as the computer's name and the name of the 662 operating system, while not strictly speaking random, will help 663 differentiate the results from those obtained by other systems. 665 The exact algorithm to generate a node ID using these data is system 666 specific, because both the data available and the functions to obtain 667 them are often very system specific. A generic approach, however is 668 to accumulate as many sources as possible into a buffer, and use a 669 message digest such as MD5 [3], take an arbitrary six bytes from the 670 hash value, and set the multicast bit as described above. 672 Other hash functions, such as SHA-1 [5], can also be used. The only 673 requirement is that the result be suitably random in the sense that 674 the outputs from a set uniformly distributed inputs are themselves 675 uniformly distributed, and that a single bit change in the input can 676 be expected to cause half of the output bits to change. 678 5. Community Considerations 680 The use of UUIDs is extremely pervasive in computing. They comprise 681 the core identifier infrastructure for many operating systems 682 (Microsoft Windows) and applications (the Mozilla browser) and in 683 many cases, become exposed to the web in many non-standard ways. This 684 specification attempts to standardize that practice as openly as 685 possible and in a way that attempts to benefit the entire Internet. 687 6. Security Considerations 689 Do not assume that UUIDs are hard to guess; they should not be used 690 as capabilities, for example. 692 Do not assume that it is easy to determine if a UUID has been 693 slightly transposed in order to redirect a reference to another 694 object. Humans do not have the ability to easily check the integrity 695 of a UUID by simply glancing at it. 697 7. Acknowledgments 699 This document draws heavily on the OSF DCE specification for UUIDs. 700 Ted Ts'o provided helpful comments, especially on the byte ordering 701 section which we mostly plagiarized from a proposed wording he 702 supplied (all errors in that section are our responsibility, 703 however). 705 Normative References 707 [1] Zahn, L., Dineen, T. and P. Leach, "Network Computing 708 Architecture", ISBN 0-13-611674-4, January 1990. 710 [2] "DCE: Remote Procedure Call", Open Group CAE Specification C309, 711 ISBN 1-85912-041-5, August 1994. 713 [3] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 714 1992. 716 [4] Moats, R., "URN Syntax", RFC 2141, May 1997. 718 [5] National Institute of Standards and Technology, "Secure Hash 719 Standard", FIPS PUB 180-1, April 1995, . 722 [6] 724 Authors' Addresses 726 Paul J. Leach 727 Microsoft 728 1 Microsoft Way 729 Redmond, WA 98052 730 US 732 Phone: +1 425-882-8080 733 EMail: paulle@microsoft.com 734 Michael Mealling 735 VeriSign, Inc. 736 21345 Ridgetop Circle 737 Dulles, VA 21345 738 US 740 Phone: +1 770-717-0732 741 EMail: michael@neonym.net 742 URI: http://www.verisignlabs.com 744 Rich Salz 745 DataPower Technology, Inc. 746 1 Alewife Center 747 Cambridge, MA 02142 748 US 750 Phone: +1 617-864-0455 751 EMail: rsalz@datapower.com 752 URI: http://www.datapower.com 754 Appendix A. Appendix A - Sample Implementation 756 This implementation consists of 5 files: uuid.h, uuid.c, sysdep.h, 757 sysdep.c and utest.c. The uuid.* files are the system independent 758 implementation of the UUID generation algorithms described above, 759 with all the optimizations described above except efficient state 760 sharing across processes included. The code has been tested on Linux 761 (Red Hat 4.0) with GCC (2.7.2), and Windows NT 4.0 with VC++ 5.0. The 762 code assumes 64-bit integer support, which makes it a lot clearer. 764 All the following source files should be considered to have the 765 following copyright notice included: 767 copyrt.h 769 /* 770 ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. 771 ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & 772 ** Digital Equipment Corporation, Maynard, Mass. 773 ** Copyright (c) 1998 Microsoft. 774 ** To anyone who acknowledges that this file is provided "AS IS" 775 ** without any express or implied warranty: permission to use, copy, 776 ** modify, and distribute this file for any purpose is hereby 777 ** granted without fee, provided that the above copyright notices and 778 ** this notice appears in all source code copies, and that none of 779 ** the names of Open Software Foundation, Inc., Hewlett-Packard 780 ** Company, or Digital Equipment Corporation be used in advertising 781 ** or publicity pertaining to distribution of the software without 782 ** specific, written prior permission. Neither Open Software 783 ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital 784 ** Equipment Corporation makes any representations about the suitability 785 ** of this software for any purpose. 786 */ 788 uuid.h 790 #include "copyrt.h" 791 #undef uuid_t 792 typedef struct { 793 unsigned32 time_low; 794 unsigned16 time_mid; 795 unsigned16 time_hi_and_version; 796 unsigned8 clock_seq_hi_and_reserved; 797 unsigned8 clock_seq_low; 798 byte node[6]; 799 } uuid_t; 801 /* uuid_create -- generate a UUID */ 802 int uuid_create(uuid_t * uuid); 804 /* uuid_create_from_name -- create a UUID using a "name" 805 from a "name space" */ 806 void uuid_create_from_name( 807 uuid_t *uuid, /* resulting UUID */ 808 uuid_t nsid, /* UUID of the namespace */ 809 void *name, /* the name from which to generate a UUID */ 810 int namelen /* the length of the name */ 811 ); 813 /* uuid_compare -- Compare two UUID's "lexically" and return 814 -1 u1 is lexically before u2 815 0 u1 is equal to u2 816 1 u1 is lexically after u2 817 Note that lexical ordering is not temporal ordering! 818 */ 819 int uuid_compare(uuid_t *u1, uuid_t *u2); 821 uuid.c 823 #include "copyrt.h" 824 #include 825 #include 826 #include 827 #include 828 #include "sysdep.h" 829 #include "uuid.h" 831 /* various forward declarations */ 832 static int read_state(unsigned16 *clockseq, uuid_time_t *timestamp, 833 uuid_node_t *node); 834 static void write_state(unsigned16 clockseq, uuid_time_t timestamp, 835 uuid_node_t node); 836 static void format_uuid_v1(uuid_t *uuid, unsigned16 clockseq, 837 uuid_time_t timestamp, uuid_node_t node); 838 static void format_uuid_v3(uuid_t *uuid, unsigned char hash[16]); 839 static void get_current_time(uuid_time_t *timestamp); 840 static unsigned16 true_random(void); 842 /* uuid_create -- generator a UUID */ 843 int uuid_create(uuid_t *uuid) 844 { 845 uuid_time_t timestamp, last_time; 846 unsigned16 clockseq; 847 uuid_node_t node; 848 uuid_node_t last_node; 849 int f; 851 /* acquire system-wide lock so we're alone */ 852 LOCK; 854 /* get time, node ID, saved state from non-volatile storage */ 855 get_current_time(×tamp); 856 get_ieee_node_identifier(&node); 857 f = read_state(&clockseq, &last_time, &last_node); 859 /* if no NV state, or if clock went backwards, or node ID changed 860 (e.g., new network card) change clockseq */ 861 if (!f || memcmp(&node, &last_node, sizeof node)) 862 clockseq = true_random(); 863 else if (timestamp < last_time) 864 clockseq++; 866 /* save the state for next time */ 867 write_state(clockseq, timestamp, node); 869 UNLOCK; 871 /* stuff fields into the UUID */ 872 format_uuid_v1(uuid, clockseq, timestamp, node); 873 return 1; 874 } 875 /* format_uuid_v1 -- make a UUID from the timestamp, clockseq, 876 and node ID */ 877 void format_uuid_v1(uuid_t* uuid, unsigned16 clock_seq, 878 uuid_time_t timestamp, uuid_node_t node) 879 { 880 /* Construct a version 1 uuid with the information we've gathered 881 plus a few constants. */ 882 uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF); 883 uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF); 884 uuid->time_hi_and_version = 885 (unsigned short)((timestamp >> 48) & 0x0FFF); 886 uuid->time_hi_and_version |= (1 << 12); 887 uuid->clock_seq_low = clock_seq & 0xFF; 888 uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8; 889 uuid->clock_seq_hi_and_reserved |= 0x80; 890 memcpy(&uuid->node, &node, sizeof uuid->node); 891 } 893 /* data type for UUID generator persistent state */ 894 typedef struct { 895 uuid_time_t ts; /* saved timestamp */ 896 uuid_node_t node; /* saved node ID */ 897 unsigned16 cs; /* saved clock sequence */ 898 } uuid_state; 900 static uuid_state st; 902 /* read_state -- read UUID generator state from non-volatile store */ 903 int read_state(unsigned16 *clockseq, uuid_time_t *timestamp, 904 uuid_node_t *node) 905 { 906 static int inited = 0; 907 FILE *fp; 909 /* only need to read state once per boot */ 910 if (!inited) { 911 fp = fopen("state", "rb"); 912 if (fp == NULL) 913 return 0; 914 fread(&st, sizeof st, 1, fp); 915 fclose(fp); 916 inited = 1; 917 } 918 *clockseq = st.cs; 919 *timestamp = st.ts; 920 *node = st.node; 921 return 1; 922 } 923 /* write_state -- save UUID generator state back to non-volatile storage */ 924 void write_state(unsigned16 clockseq, uuid_time_t timestamp, 925 uuid_node_t node) 926 { 927 static int inited = 0; 928 static uuid_time_t next_save; 929 FILE* fp; 931 if (!inited) { 932 next_save = timestamp; 933 inited = 1; 934 } 936 /* always save state to volatile shared state */ 937 st.cs = clockseq; 938 st.ts = timestamp; 939 st.node = node; 940 if (timestamp >= next_save) { 941 fp = fopen("state", "wb"); 942 fwrite(&st, sizeof st, 1, fp); 943 fclose(fp); 944 /* schedule next save for 10 seconds from now */ 945 next_save = timestamp + (10 * 10 * 1000 * 1000); 946 } 947 } 949 /* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch. 950 Compensate for the fact that real clock resolution is 951 less than 100ns. */ 952 void get_current_time(uuid_time_t *timestamp) 953 { 954 static int inited = 0; 955 static uuid_time_t time_last; 956 static unsigned16 uuids_this_tick; 957 uuid_time_t time_now; 959 if (!inited) { 960 get_system_time(&time_now); 961 uuids_this_tick = UUIDS_PER_TICK; 962 inited = 1; 963 } 965 for ( ; ; ) { 966 get_system_time(&time_now); 968 /* if clock reading changed since last UUID generated, */ 969 if (time_last != time_now) { 970 /* reset count of uuids gen'd with this clock reading */ 971 uuids_this_tick = 0; 972 break; 973 } 974 if (uuids_this_tick < UUIDS_PER_TICK) { 975 uuids_this_tick++; 976 break; 977 } 978 /* going too fast for our clock; spin */ 979 } 980 /* add the count of uuids to low order bits of the clock reading */ 981 *timestamp = time_now + uuids_this_tick; 982 } 984 /* true_random -- generate a crypto-quality random number. 985 **This sample doesn't do that.** */ 986 static unsigned16 true_random(void) 987 { 988 static int inited = 0; 989 uuid_time_t time_now; 991 if (!inited) { 992 get_system_time(&time_now); 993 time_now = time_now / UUIDS_PER_TICK; 994 srand((unsigned int)(((time_now >> 32) ^ time_now) & 0xffffffff)); 995 inited = 1; 996 } 998 return rand(); 999 } 1001 /* uuid_create_from_name -- create a UUID using a "name" from a "name 1002 space" */ 1003 void uuid_create_from_name(uuid_t *uuid, uuid_t nsid, void *name, 1004 int namelen) 1005 { 1006 MD5_CTX c; 1007 unsigned char hash[16]; 1008 uuid_t net_nsid; 1010 /* put name space ID in network byte order so it hashes the same 1011 no matter what endian machine we're on */ 1012 net_nsid = nsid; 1013 htonl(net_nsid.time_low); 1014 htons(net_nsid.time_mid); 1015 htons(net_nsid.time_hi_and_version); 1017 MD5Init(&c); 1018 MD5Update(&c, &net_nsid, sizeof net_nsid); 1019 MD5Update(&c, name, namelen); 1020 MD5Final(hash, &c); 1022 /* the hash is in network byte order at this point */ 1023 format_uuid_v3(uuid, hash); 1024 } 1026 /* format_uuid_v3 -- make a UUID from a (pseudo)random 128-bit number */ 1027 void format_uuid_v3(uuid_t *uuid, unsigned char hash[16]) 1028 { 1029 /* convert UUID to local byte order */ 1030 memcpy(uuid, hash, sizeof *uuid); 1031 ntohl(uuid->time_low); 1032 ntohs(uuid->time_mid); 1033 ntohs(uuid->time_hi_and_version); 1035 /* put in the variant and version bits */ 1036 uuid->time_hi_and_version &= 0x0FFF; 1037 uuid->time_hi_and_version |= (3 << 12); 1038 uuid->clock_seq_hi_and_reserved &= 0x3F; 1039 uuid->clock_seq_hi_and_reserved |= 0x80; 1040 } 1042 /* uuid_compare -- Compare two UUID's "lexically" and return */ 1043 #define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1; 1044 int uuid_compare(uuid_t *u1, uuid_t *u2) 1045 { 1046 int i; 1048 CHECK(u1->time_low, u2->time_low); 1049 CHECK(u1->time_mid, u2->time_mid); 1050 CHECK(u1->time_hi_and_version, u2->time_hi_and_version); 1051 CHECK(u1->clock_seq_hi_and_reserved, u2->clock_seq_hi_and_reserved); 1052 CHECK(u1->clock_seq_low, u2->clock_seq_low) 1053 for (i = 0; i < 6; i++) { 1054 if (u1->node[i] < u2->node[i]) 1055 return -1; 1056 if (u1->node[i] > u2->node[i]) 1057 return 1; 1058 } 1059 return 0; 1060 } 1061 #undef CHECK 1063 sysdep.h 1065 #include "copyrt.h" 1066 /* remove the following define if you aren't running WIN32 */ 1067 #define WININC 0 1069 #ifdef WININC 1070 #include 1071 #else 1072 #include 1073 #include 1074 #include 1075 #endif 1077 #include "global.h" 1078 /* change to point to where MD5 .h's live; RFC 1321 has sample 1079 implementation */ 1080 #include "md5.h" 1082 /* set the following to the number of 100ns ticks of the actual 1083 resolution of your system's clock */ 1084 #define UUIDS_PER_TICK 1024 1086 /* Set the following to a calls to get and release a global lock */ 1087 #define LOCK 1088 #define UNLOCK 1090 typedef unsigned long unsigned32; 1091 typedef unsigned short unsigned16; 1092 typedef unsigned char unsigned8; 1093 typedef unsigned char byte; 1095 /* Set this to what your compiler uses for 64-bit data type */ 1096 #ifdef WININC 1097 #define unsigned64_t unsigned __int64 1098 #define I64(C) C 1099 #else 1100 #define unsigned64_t unsigned long long 1101 #define I64(C) C##LL 1102 #endif 1104 typedef unsigned64_t uuid_time_t; 1105 typedef struct { 1106 char nodeID[6]; 1107 } uuid_node_t; 1109 void get_ieee_node_identifier(uuid_node_t *node); 1110 void get_system_time(uuid_time_t *uuid_time); 1111 void get_random_info(char seed[16]); 1112 sysdep.c 1114 #include "copyrt.h" 1115 #include 1116 #include "sysdep.h" 1118 /* system dependent call to get IEEE node ID. 1119 This sample implementation generates a random node ID. */ 1120 void get_ieee_node_identifier(uuid_node_t *node) 1121 { 1122 static inited = 0; 1123 static uuid_node_t saved_node; 1124 char seed[16]; 1125 FILE *fp; 1127 if (!inited) { 1128 fp = fopen("nodeid", "rb"); 1129 if (fp) { 1130 fread(&saved_node, sizeof saved_node, 1, fp); 1131 fclose(fp); 1132 } 1133 else { 1134 get_random_info(seed); 1135 seed[0] |= 0x80; 1136 memcpy(&saved_node, seed, sizeof saved_node); 1137 fp = fopen("nodeid", "wb"); 1138 if (fp) { 1139 fwrite(&saved_node, sizeof saved_node, 1, fp); 1140 fclose(fp); 1141 } 1142 } 1143 inited = 1; 1144 } 1146 *node = saved_node; 1147 } 1149 /* system dependent call to get the current system time. Returned as 1150 100ns ticks since UUID epoch, but resolution may be less than 100ns. */ 1151 #ifdef _WINDOWS_ 1153 void get_system_time(uuid_time_t *uuid_time) 1154 { 1155 ULARGE_INTEGER time; 1157 /* NT keeps time in FILETIME format which is 100ns ticks since 1158 Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. 1159 The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) 1160 + 18 years and 5 leap days. */ 1161 GetSystemTimeAsFileTime((FILETIME *)&time); 1162 time.QuadPart += 1163 (unsigned __int64) (1000*1000*10) // seconds 1164 * (unsigned __int64) (60 * 60 * 24) // days 1165 * (unsigned __int64) (17+30+31+365*18+5); // # of days 1166 *uuid_time = time.QuadPart; 1167 } 1169 void get_random_info(char seed[16]) 1170 { 1171 MD5_CTX c; 1172 struct { 1173 MEMORYSTATUS m; 1174 SYSTEM_INFO s; 1175 FILETIME t; 1176 LARGE_INTEGER pc; 1177 DWORD tc; 1178 DWORD l; 1179 char hostname[MAX_COMPUTERNAME_LENGTH + 1]; 1180 } r; 1182 MD5Init(&c); 1183 GlobalMemoryStatus(&r.m); 1184 GetSystemInfo(&r.s); 1185 GetSystemTimeAsFileTime(&r.t); 1186 QueryPerformanceCounter(&r.pc); 1187 r.tc = GetTickCount(); 1188 r.l = MAX_COMPUTERNAME_LENGTH + 1; 1189 GetComputerName(r.hostname, &r.l); 1190 MD5Update(&c, &r, sizeof r); 1191 MD5Final(seed, &c); 1192 } 1194 #else 1196 void get_system_time(uuid_time_t *uuid_time) 1197 { 1198 struct timeval tp; 1200 gettimeofday(&tp, (struct timezone *)0); 1202 /* Offset between UUID formatted times and Unix formatted times. 1203 UUID UTC base time is October 15, 1582. 1204 Unix base time is January 1, 1970.*/ 1205 *uuid_time = ((unsigned64)tp.tv_sec * 10000000) 1206 + ((unsigned64)tp.tv_usec * 10) 1207 + I64(0x01B21DD213814000); 1209 } 1211 void get_random_info(char seed[16]) 1212 { 1213 MD5_CTX c; 1214 struct { 1215 struct sysinfo s; 1216 struct timeval t; 1217 char hostname[257]; 1218 } r; 1220 MD5Init(&c); 1221 sysinfo(&r.s); 1222 gettimeofday(&r.t, (struct timezone *)0); 1223 gethostname(r.hostname, 256); 1224 MD5Update(&c, &r, sizeof r); 1225 MD5Final(seed, &c); 1226 } 1228 #endif 1230 utest.c 1232 #include "copyrt.h" 1233 #include "sysdep.h" 1234 #include 1235 #include "uuid.h" 1237 uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ 1238 0x6ba7b810, 1239 0x9dad, 1240 0x11d1, 1241 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1242 }; 1244 /* puid -- print a UUID */ 1245 void puid(uuid_t u) 1246 { 1247 int i; 1249 printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid, 1250 u.time_hi_and_version, u.clock_seq_hi_and_reserved, 1251 u.clock_seq_low); 1252 for (i = 0; i < 6; i++) 1253 printf("%2.2x", u.node[i]); 1254 printf("\n"); 1255 } 1256 /* Simple driver for UUID generator */ 1257 void main(int argc, char **argv) 1258 { 1259 uuid_t u; 1260 int f; 1262 uuid_create(&u); 1263 printf("uuid_create(): "); puid(u); 1265 f = uuid_compare(&u, &u); 1266 printf("uuid_compare(u,u): %d\n", f); /* should be 0 */ 1267 f = uuid_compare(&u, &NameSpace_DNS); 1268 printf("uuid_compare(u, NameSpace_DNS): %d\n", f); /* s.b. 1 */ 1269 f = uuid_compare(&NameSpace_DNS, &u); 1270 printf("uuid_compare(NameSpace_DNS, u): %d\n", f); /* s.b. -1 */ 1271 uuid_create_from_name(&u, NameSpace_DNS, "www.widgets.com", 15); 1272 printf("uuid_create_from_name(): "); puid(u); 1273 } 1275 Appendix B. Appendix B - Sample output of utest 1277 uuid_create(): 7d444840-9dc0-11d1-b245-5ffdce74fad2 1278 uuid_compare(u,u): 0 1279 uuid_compare(u, NameSpace_DNS): 1 1280 uuid_compare(NameSpace_DNS, u): -1 1281 uuid_create_from_name(): e902893a-9d22-3c7e-a7b8-d6e313b71d9f 1283 Appendix C. Appendix C - Some name space IDs 1285 This appendix lists the name space IDs for some potentially 1286 interesting name spaces, as initialized C structures and in the 1287 string representation defined above. 1289 /* Name string is a fully-qualified domain name */ 1290 uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ 1291 0x6ba7b810, 1292 0x9dad, 1293 0x11d1, 1294 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1295 }; 1297 /* Name string is a URL */ 1298 uuid_t NameSpace_URL = { /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */ 1299 0x6ba7b811, 1300 0x9dad, 1301 0x11d1, 1302 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1303 }; 1305 /* Name string is an ISO OID */ 1306 uuid_t NameSpace_OID = { /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */ 1307 0x6ba7b812, 1308 0x9dad, 1309 0x11d1, 1310 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1311 }; 1313 /* Name string is an X.500 DN (in DER or a text output format) */ 1314 uuid_t NameSpace_X500 = { /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */ 1315 0x6ba7b814, 1316 0x9dad, 1317 0x11d1, 1318 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 1319 }; 1321 Intellectual Property Statement 1323 The IETF takes no position regarding the validity or scope of any 1324 intellectual property or other rights that might be claimed to 1325 pertain to the implementation or use of the technology described in 1326 this document or the extent to which any license under such rights 1327 might or might not be available; neither does it represent that it 1328 has made any effort to identify any such rights. Information on the 1329 IETF's procedures with respect to rights in standards-track and 1330 standards-related documentation can be found in BCP-11. Copies of 1331 claims of rights made available for publication and any assurances of 1332 licenses to be made available, or the result of an attempt made to 1333 obtain a general license or permission for the use of such 1334 proprietary rights by implementors or users of this specification can 1335 be obtained from the IETF Secretariat. 1337 The IETF invites any interested party to bring to its attention any 1338 copyrights, patents or patent applications, or other proprietary 1339 rights which may cover technology that may be required to practice 1340 this standard. Please address the information to the IETF Executive 1341 Director. 1343 Full Copyright Statement 1345 Copyright (C) The Internet Society (2004). All Rights Reserved. 1347 This document and translations of it may be copied and furnished to 1348 others, and derivative works that comment on or otherwise explain it 1349 or assist in its implementation may be prepared, copied, published 1350 and distributed, in whole or in part, without restriction of any 1351 kind, provided that the above copyright notice and this paragraph are 1352 included on all such copies and derivative works. However, this 1353 document itself may not be modified in any way, such as by removing 1354 the copyright notice or references to the Internet Society or other 1355 Internet organizations, except as needed for the purpose of 1356 developing Internet standards in which case the procedures for 1357 copyrights defined in the Internet Standards process must be 1358 followed, or as required to translate it into languages other than 1359 English. 1361 The limited permissions granted above are perpetual and will not be 1362 revoked by the Internet Society or its successors or assignees. 1364 This document and the information contained herein is provided on an 1365 "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING 1366 TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 1367 BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION 1368 HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 1369 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 1371 Acknowledgment 1373 Funding for the RFC Editor function is currently provided by the 1374 Internet Society.