A Python UPnP Media Server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1041 lines
36 KiB

  1. Network Working Group Paul J. Leach, Microsoft
  2. INTERNET-DRAFT Rich Salz, Open Group
  3. <draft-leach-uuids-guids-00.txt>
  4. Category: Informational
  5. Expires August 24, 1997 February 24, 1997
  6. UUIDs and GUIDs
  7. STATUS OF THIS MEMO
  8. This document is an Internet-Draft. Internet-Drafts are working
  9. documents of the Internet Engineering Task Force (IETF), its areas,
  10. and its working groups. Note that other groups may also distribute
  11. working documents as Internet-Drafts.
  12. Internet-Drafts are draft documents valid for a maximum of six months
  13. and may be updated, replaced, or obsoleted by other documents at any
  14. time. It is inappropriate to use Internet-Drafts as reference
  15. material or to cite them other than as "work in progress".
  16. To learn the current status of any Internet-Draft, please check the
  17. "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow
  18. Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
  19. munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
  20. ftp.isi.edu (US West Coast).
  21. Distribution of this document is unlimited. Please send comments to
  22. the authors or the CIFS mailing list at <cifs@listserv.msn.com>.
  23. Discussions of the mailing list are archived at
  24. <URL:http://microsoft.ease.lsoft.com/archives/CIFS.html>.
  25. ABSTRACT
  26. This specification defines the format of UUIDs (Universally Unique
  27. IDentifier), also known as GUIDs (Globally Unique IDentifier). A UUID
  28. is 128 bits long, and if generated according to the one of the
  29. mechanisms in this document, is either guaranteed to be different
  30. from all other UUIDs/GUIDs generated until 3400 A.D. or extremely
  31. likely to be different (depending on the mechanism chosen). UUIDs
  32. were originally used in the Network Computing System (NCS) [1] and
  33. later in the Open Software Foundation's (OSF) Distributed Computing
  34. Environment [2].
  35. This specification is derived from the latter specification with the
  36. kind permission of the OSF.
  37. Table of Contents
  38. 1. Introduction......................................................2
  39. [Page 1]
  40. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  41. 2. Motivation........................................................2
  42. 3. Specification.....................................................3
  43. 3.1 Format ..........................................................3
  44. 3.2 Algorithms for Creating a UUID ..................................5
  45. 3.2.1 Clock Sequence...............................................5
  46. 3.2.2 System Reboot................................................6
  47. 3.2.3 Clock Adjustment.............................................7
  48. 3.2.4 Clock Overrun................................................7
  49. 3.2.5 UUID Generation..............................................7
  50. 3.3 String Representation of UUIDs ..................................8
  51. 3.4 Comparing UUIDs .................................................9
  52. 3.5 Byte order of UUIDs .............................................9
  53. 4. Node IDs when no IEEE 802 network card is available...............9
  54. 5. Obtaining IEEE 802 addresses.....................................11
  55. 6. Security Considerations..........................................12
  56. 7. Acknowledgements.................................................12
  57. 8. References.......................................................12
  58. 9. Authors' addresses...............................................12
  59. 1. Introduction
  60. This specification defines the format of UUIDs (Universally Unique
  61. IDentifiers), also known as GUIDs (Globally Unique IDentifiers). A
  62. UUID is 128 bits long, and if generated according to the one of the
  63. mechanisms in this document, is either guaranteed to be different
  64. from all other UUIDs/GUIDs generated until 3400 A.D. or extremely
  65. likely to be different (depending on the mechanism chosen).
  66. 2. Motivation
  67. One of the main reasons for using UUIDs is that no centralized
  68. authority is required to administer them (beyond the one that
  69. allocates IEEE 802.1 node identifiers). As a result, generation on
  70. Leach, Salz expires July 1997 [Page 2]
  71. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  72. demand can be completely automated, and they can be used for a wide
  73. variety of purposes. The UUID generation algorithm described here
  74. supports very high allocation rates: 10 million per second per
  75. machine if you need it, so that they could even be used as
  76. transaction IDs.
  77. UUIDs are fixed-size (128-bits) which is reasonably small relative to
  78. other alternatives. This fixed, relatively small size lends itself
  79. well to sorting, ordering, and hashing of all sorts, storing in
  80. databases, simple allocation, and ease of programming in general.
  81. 3. Specification
  82. A UUID is an identifier that is unique across both space and time,
  83. with respect to the space of all UUIDs. To be precise, the UUID
  84. consists of a finite bit space. Thus the time value used for
  85. constructing a UUID is limited and will roll over in the future
  86. (approximately at A.D. 3400, based on the specified algorithm). A
  87. UUID can be used for multiple purposes, from tagging objects with an
  88. extremely short lifetime, to reliably identifying very persistent
  89. objects across a network.
  90. The generation of UUIDs does not require that a registration
  91. authority be contacted for each identifier. Instead, it requires a
  92. unique value over space for each UUID generator. This spatially
  93. unique value is specified as an IEEE 802 address, which is usually
  94. already available to network-connected systems. This 48-bit address
  95. can be assigned based on an address block obtained through the IEEE
  96. registration authority. This section of the UUID specification
  97. assumes the availability of an IEEE 802 address to a system desiring
  98. to generate a UUID, but if one is not available section 4 specifies a
  99. way to generate a probabilistically unique one that can not conflict
  100. with any properly assigned IEEE 802 address.
  101. 3.1 Format
  102. The following table gives the format of a UUID. The UUID consists of
  103. a record of 16 octets. The fields are in order of significance for
  104. comparison purposes, with "time_low" the most significant, and "node"
  105. the least significant.
  106. Field Data Octet Note
  107. Type #
  108. time_low unsigned 0-3 The low field of the
  109. 32 bit timestamp.
  110. integer
  111. time_mid unsigned 4-5 The middle field of the
  112. 16 bit timestamp.
  113. integer
  114. Leach, Salz expires July 1997 [Page 3]
  115. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  116. time_hi_and_version unsigned 6-7 The high field of the
  117. 16 bit timestamp multiplexed
  118. integer with the version number.
  119. clock_seq_hi_and_reserved unsigned The high field of the
  120. 8 bit clock sequence 8
  121. integer multiplexed with the
  122. variant.
  123. clock_seq_low unsigned 9 The low field of the
  124. 8 bit clock sequence.
  125. integer
  126. node unsigned The spatially unique
  127. 48 bit node identifier. 10-15
  128. integer
  129. To minimize confusion about bit assignments within octets, the UUID
  130. record definition is defined only in terms of fields that are
  131. integral numbers of octets. The version number is in the most
  132. significant 4 bits of the time stamp (time_hi), and the variant field
  133. is in the most significant 3 bits of the clock sequence
  134. (clock_seq_high).
  135. The timestamp is a 60 bit value. For UUID version 1, this is
  136. represented by Coordinated Universal Time (UTC) as a count of 100-
  137. nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of
  138. Gregorian reform to the Christian calendar).
  139. The following table lists currently defined versions of the UUID.
  140. Msb0 Msb1 Msb2 Msb3 Version Description
  141. 0 0 0 1 1 The version specified
  142. in this document.
  143. 0 0 1 0 2 Reserved for DCE
  144. Security version, with
  145. embedded POSIX UIDs.
  146. The variant field determines the layout of the UUID. The structure of
  147. UUIDs is fixed across different versions within a variant, but not
  148. across variants; hence, other UUID variants may not interoperate with
  149. the UUID variant specified in this document. Interoperability of
  150. UUIDs is defined as the applicability of operations such as string
  151. conversion, comparison, and lexical ordering across different
  152. systems. The variant field consists of a variable number of the msbs
  153. of the clock_seq_hi_and_reserved field.
  154. The following table lists the contents of the variant field.
  155. Leach, Salz expires July 1997 [Page 4]
  156. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  157. Msb0 Msb1 Msb2 Description
  158. 0 - - Reserved, NCS backward compatibility.
  159. 1 0 - The variant specified in this document.
  160. 1 1 0 Reserved, Microsoft Corporation GUID.
  161. 1 1 1 Reserved for future definition.
  162. The clock sequence is required to detect potential losses of
  163. monotonicity of the clock. Thus, this value marks discontinuities and
  164. prevents duplicates. An algorithm for generating this value is
  165. outlined in the _Clock Sequence_ section below.
  166. The clock sequence is encoded in the 6 least significant bits of the
  167. clock_seq_hi_and_reserved field and in the clock_seq_low field.
  168. The node field consists of the IEEE address, usually the host
  169. address. For systems with multiple IEEE 802 nodes, any available node
  170. address can be used. The lowest addressed octet (octet number 10)
  171. contains the global/local bit and the unicast/multicast bit, and is
  172. the first octet of the address transmitted on an 802.3 LAN.
  173. Depending on the network data representation, the multi-octet
  174. unsigned integer fields are subject to byte swapping when
  175. communicated between different endian machines.
  176. The nil UUID is special form of UUID that is specified to have all
  177. 128 bits set to 0 (zero).
  178. 3.2 Algorithms for Creating a UUID
  179. Various aspects of the algorithm for creating a UUID are discussed in
  180. the following sections. UUID generation requires a guarantee of
  181. uniqueness within the node ID for a given variant and version.
  182. Interoperability is provided by complying with the specified data
  183. structure. To prevent possible UUID collisions, which could be caused
  184. by different implementations on the same node, compliance with the
  185. algorithm specified here is required.
  186. 3.2.1 Clock Sequence
  187. The clock sequence value must be changed whenever:
  188. - the UUID generator detects that the local value of UTC has gone
  189. backward.
  190. - the UUID generator has lost its state of the last value of UTC
  191. used, indicating that time may have gone backward; this is typically
  192. the case on reboot.
  193. Leach, Salz expires July 1997 [Page 5]
  194. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  195. While a node is operational, the UUID service always saves the last
  196. UTC used to create a UUID. Each time a new UUID is created, the
  197. current UTC is compared to the saved value and if either the current
  198. value is less (the non-monotonic clock case) or the saved value was
  199. lost, then the clock sequence is incremented modulo 16,384, thus
  200. avoiding production of duplicate UUIDs.
  201. The clock sequence must be initialized to a random number to minimize
  202. the correlation across systems. This provides maximum protection
  203. against node identifiers that may move or switch from system to
  204. system rapidly. The initial value MUST NOT be correlated to the node
  205. identifier.
  206. The rule of initializing the clock sequence to a random value is
  207. waived if, and only if all of the following are true:
  208. - The clock sequence value is stored in non-volatile storage.
  209. - The system is manufactured such that the IEEE address ROM is
  210. designed to be inseparable from the system by either the user or
  211. field service, so that it cannot be moved to another system.
  212. - The manufacturing process guarantees that only new IEEE address
  213. ROMs are used.
  214. - Any field service, remanufacturing or rebuilding process that could
  215. change the value of the clock sequence must reinitialise it to a
  216. random value.
  217. In other words, the system constraints prevent duplicates caused by
  218. possible migration of the IEEE address, while the operational system
  219. itself can protect against non-monotonic clocks, except in the case
  220. of field service intervention. At manufacturing time, such a system
  221. may initialise the clock sequence to any convenient value.
  222. 3.2.2 System Reboot
  223. There are two possibilities when rebooting a system:
  224. - the UUID generator state - the last UTC, adjustment, and clock
  225. sequence - of the UUID service has been restored from non-volatile
  226. store
  227. - the state of the last UTC or adjustment has been lost.
  228. If the state variables have been restored, the UUID generator just
  229. continues as normal. Alternatively, if the state variables cannot be
  230. restored, they are reinitialised, and the clock sequence is changed.
  231. If the clock sequence is stored in non-volatile store, it is
  232. incremented; otherwise, it is reinitialised to a new random value.
  233. Leach, Salz expires July 1997 [Page 6]
  234. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  235. 3.2.3 Clock Adjustment
  236. UUIDs may be created at a rate greater than the system clock
  237. resolution. Therefore, the system must also maintain an adjustment
  238. value to be added to the lower-order bits of the time. Logically,
  239. each time the system clock ticks, the adjustment value is cleared.
  240. Every time a UUID is generated, the current adjustment value is read
  241. and incremented atomically, then added to the UTC time field of the
  242. UUID.
  243. 3.2.4 Clock Overrun
  244. The 100 nanosecond granularity of time should prove sufficient even
  245. for bursts of UUID creation in high-performance multiprocessors. If a
  246. system overruns the clock adjustment by requesting too many UUIDs
  247. within a single system clock tick, the UUID service may raise an
  248. exception, handled in a system or process-dependent manner either by:
  249. - terminating the requester
  250. - reissuing the request until it succeeds
  251. - stalling the UUID generator until the system clock catches up.
  252. If the processors overrun the UUID generation frequently, additional
  253. node identifiers and clocks may need to be added.
  254. 3.2.5 UUID Generation
  255. UUIDs are generated according to the following algorithm:
  256. - Determine the values for the UTC-based timestamp and clock sequence
  257. to be used in the UUID, as described above.
  258. - For the purposes of this algorithm, consider the timestamp to be a
  259. 60-bit unsigned integer and the clock sequence to be a 14-bit
  260. unsigned integer. Sequentially number the bits in a field, starting
  261. from 0 (zero) for the least significant bit.
  262. - Set the time_low field equal to the least significant 32-bits (bits
  263. numbered 0 to 31 inclusive) of the time stamp in the same order of
  264. significance.
  265. - Set the time_mid field equal to the bits numbered 32 to 47
  266. inclusive of the time stamp in the same order of significance.
  267. - Set the 12 least significant bits (bits numbered 0 to 11 inclusive)
  268. of the time_hi_and_version field equal to the bits numbered 48 to 59
  269. inclusive of the time stamp in the same order of significance.
  270. - Set the 4 most significant bits (bits numbered 12 to 15 inclusive)
  271. of the time_hi_and_version field to the 4-bit version number
  272. corresponding to the UUID version being created, as shown in the
  273. table above.
  274. Leach, Salz expires July 1997 [Page 7]
  275. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  276. - Set the clock_seq_low field to the 8 least significant bits (bits
  277. numbered 0 to 7 inclusive) of the clock sequence in the same order of
  278. significance.
  279. - Set the 6 least significant bits (bits numbered 0 to 5 inclusive)
  280. of the clock_seq_hi_and_reserved field to the 6 most significant bits
  281. (bits numbered 8 to 13 inclusive) of the clock sequence in the same
  282. order of significance.
  283. - Set the 2 most significant bits (bits numbered 6 and 7) of the
  284. clock_seq_hi_and_reserved to 0 and 1, respectively.
  285. - Set the node field to the 48-bit IEEE address in the same order of
  286. significance as the address.
  287. 3.3 String Representation of UUIDs
  288. For use in human readable text, a UUID string representation is
  289. specified as a sequence of fields, some of which are separated by
  290. single dashes.
  291. Each field is treated as an integer and has its value printed as a
  292. zero-filled hexadecimal digit string with the most significant digit
  293. first. The hexadecimal values a to f inclusive are output as lower
  294. case characters, and are case insensitive on input. The sequence is
  295. the same as the UUID constructed type.
  296. The formal definition of the UUID string representation is provided
  297. by the following extended BNF:
  298. UUID = <time_low> "-" <time_mid> "-"
  299. <time_high_and_version> "-"
  300. <clock_seq_and_reserved>
  301. <clock_seq_low> "-" <node>
  302. time_low = 4*<hexOctet>
  303. time_mid = 2*<hexOctet>
  304. time_high_and_version = 2*<hexOctet>
  305. clock_seq_and_reserved = <hexOctet>
  306. clock_seq_low = <hexOctet>
  307. node = 6*<hexOctet
  308. hexOctet = <hexDigit> <hexDigit>
  309. hexDigit =
  310. "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
  311. | "a" | "b" | "c" | "d" | "e" | "f"
  312. | "A" | "B" | "C" | "D" | "E" | "F"
  313. The following is an example of the string representation of a UUID:
  314. f81d4fae-7dec-11d0-a765-00a0c91e6bf6
  315. Leach, Salz expires July 1997 [Page 8]
  316. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  317. 3.4 Comparing UUIDs
  318. Consider each field of the UUID to be an unsigned integer as shown in
  319. the table in section 3.1. Then, to compare a pair of UUIDs,
  320. arithmetically compare the corresponding fields from each UUID in
  321. order of significance and according to their data type. Two UUIDs are
  322. equal if and only if all the corresponding fields are equal. The
  323. first of two UUIDs follows the second if the most significant field
  324. in which the UUIDs differ is greater for the first UUID. The first of
  325. a pair of UUIDs precedes the second if the most significant field in
  326. which the UUIDs differ is greater for the second UUID.
  327. 3.5 Byte order of UUIDs
  328. UUIDs may be transmitted in many different forms, some of which may
  329. be dependent on the presentation or application protocol where the
  330. UUID may be used. In such cases, the order, sizes and byte orders of
  331. the UUIDs fields on the wire will depend on the relevant presentation
  332. or application protocol. However, it is strongly RECOMMENDED that
  333. the order of the fields conform with ordering set out in section 3.1
  334. above. Furthermore, the payload size of each field in the application
  335. or presentation protocol MUST be large enough that no information
  336. lost in the process of encoding them for transmission.
  337. In the absence of explicit application or presentation protocol
  338. specification to the contrary, a UUID is encoded as a 128-bit object,
  339. as follows: the fields are encoded as 16 octets, with the sizes and
  340. order of the fields defined in section 3.1, and with each field
  341. encoded with the Most Significant Byte first (also known as network
  342. byte order).
  343. 0 1 2 3
  344. 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
  345. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  346. | time_high |
  347. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  348. | time_mid | time_hi_and_version |
  349. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  350. |clk_seq_hi_res | clk_seq_low | node (0-1) |
  351. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  352. | node (2-5) |
  353. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  354. 4. Node IDs when no IEEE 802 network card is available
  355. If a system wants to generate UUIDs but has no IEE 802 compliant
  356. network card or other source of IEEE 802 addresses, then this section
  357. describes how to generate one.
  358. The ideal solution is to obtain a 47 bit cryptographic quality random
  359. number, and use it as the low 47 bits of the node ID, with the most
  360. Leach, Salz expires July 1997 [Page 9]
  361. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  362. significant bit of the first octet of the node ID set to 1. This bit
  363. is the unicast/multicast bit, which will never be set in IEEE 802
  364. addresses obtained from network cards; hence, there can never be a
  365. conflict between UUIDs generated by machines with and without network
  366. cards.
  367. If a system does not have a primitive to generate cryptographic
  368. quality random numbers, then in most systems there are usually a
  369. fairly large number of sources of randomness available from which one
  370. can be generated. Such sources are system specific, but often
  371. include:
  372. - the percent of memory in use
  373. - the size of main memory in bytes
  374. - the amount of free main memory in bytes
  375. - the size of the paging or swap file in bytes
  376. - free bytes of paging or swap file
  377. - the total size of user virtual address space in bytes
  378. - the total available user address space bytes
  379. - the size of boot disk drive in bytes
  380. - the free disk space on boot drive in bytes
  381. - the current time
  382. - the amount of time since the system booted
  383. - the individual sizes of files in various system directories
  384. - the creation, last read, and modification times of files in various
  385. system directories
  386. - the utilization factors of various system resources (heap, etc.)
  387. - current mouse cursor position
  388. - current caret position
  389. - current number of running processes, threads
  390. - handles or IDs of the desktop window and the active window
  391. - the value of stack pointer of the caller
  392. - the process and thread ID of caller
  393. Leach, Salz expires July 1997 [Page 10]
  394. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  395. - various processor architecture specific performance counters
  396. (instructions executed, cache misses, TLB misses)
  397. (Note that it precisely the above kinds of sources of randomness that
  398. are used to seed cryptographic quality random number generators on
  399. systems without special hardware for their construction.)
  400. In addition, items such as the computer's name and the name of the
  401. operating system, while not strictly speaking random, will help
  402. differentiate the results from those obtained by other systems.
  403. The exact algorithm to generate a node ID using these data is system
  404. specific, because both the data available and the functions to obtain
  405. them are often very system specific. However, assuming that one can
  406. concatenate all the values from the randomness sources into a buffer,
  407. and that a cryptographic hash function such as MD5 [3] is available,
  408. the following code will compute a node ID:
  409. #include <md5.h>
  410. #define HASHLEN 16
  411. void GenNodeID(
  412. unsigned char * pDataBuf, // concatenated "randomness values"
  413. long cData, // size of randomness values
  414. unsigned char NodeID[6] // node ID
  415. )
  416. {
  417. int i, j, k;
  418. unsigned char Hash[HASHLEN];
  419. MD_CTX context;
  420. MDInit (&context);
  421. MDUpdate (&context, pDataBuf, cData);
  422. MDFinal (Hash, &context);
  423. for (j = 0; j<6; j++) NodeId[j]=0;
  424. for (i = 0,j = 0; i < HASHLEN; i++) {
  425. NodeID[j++] ^= Hash[i];
  426. if (j == 6) j = 0;
  427. };
  428. NodeID[0] |= 0x80; // set the multicast bit
  429. };
  430. Other hash functions, such as SHA-1 [4], can also be used (in which
  431. case HASHLEN will be 20). The only requirement is that the result be
  432. suitably random _ in the sense that the outputs from a set uniformly
  433. distributed inputs are themselves uniformly distributed, and that a
  434. single bit change in the input can be expected to cause half of the
  435. output bits to change.
  436. 5. Obtaining IEEE 802 addresses
  437. The following URL
  438. Leach, Salz expires July 1997 [Page 11]
  439. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  440. http://stdsbbs.ieee.org/products/oui/forms/index.html
  441. contains information on how to obtain an IEEE 802 address block. Cost
  442. is $1000 US.
  443. 6. Security Considerations
  444. It should not be assumed that UUIDs are hard to guess; they should
  445. not be used as capabilities.
  446. 7. Acknowledgements
  447. This document draws heavily on the OSF DCE specification for UUIDs.
  448. Ted Ts'o provided helpful comments, especially on the byte ordering
  449. section which we mostly plagiarized from a proposed wording he
  450. supplied (all errors in that section are our responsibility,
  451. however).
  452. 8. References
  453. [1] Lisa Zahn, et. al., Network Computing Architecture, Prentice
  454. Hall, Englewood Cliffs, NJ, 1990
  455. [2] DCE: Remote Procedure Call, Open Group CAE Specification C309
  456. ISBN 1-85912-041-5 28cm. 674p. pbk. 1,655g. 8/94
  457. [3] R. Rivest, RFC 1321, "The MD5 Message-Digest Algorithm",
  458. 04/16/1992.
  459. [4] SHA Spec - TBD
  460. 9. Authors' addresses
  461. Paul J. Leach
  462. Microsoft
  463. 1 Microsoft Way
  464. Redmond, WA, 98052, U.S.A.
  465. Email:
  466. paulle@microsoft.com
  467. Rich Salz
  468. The Open Group
  469. 11 Cambridge Center
  470. Cambridge, MA 02142, U.S.A.
  471. Email r.salz@opengroup.org
  472. Appendix A _ UUID Reference Implementation
  473. /*
  474. ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
  475. Leach, Salz expires July 1997 [Page 12]
  476. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  477. ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
  478. ** Digital Equipment Corporation, Maynard, Mass.
  479. ** To anyone who acknowledges that this file is provided "AS IS"
  480. ** without any express or implied warranty: permission to use, copy,
  481. ** modify, and distribute this file for any purpose is hereby
  482. ** granted without fee, provided that the above copyright notices and
  483. ** this notice appears in all source code copies, and that none of
  484. ** the names of Open Software Foundation, Inc., Hewlett-Packard
  485. ** Company, or Digital Equipment Corporation be used in advertising
  486. ** or publicity pertaining to distribution of the software without
  487. ** specific, written prior permission. Neither Open Software
  488. ** Foundation, Inc., Hewlett-Packard Company, nor Digital Equipment
  489. ** Corporation makes any representations about the suitability of
  490. ** this software for any purpose.
  491. */
  492. #include <sys/types.h>
  493. #include <sys/time.h>
  494. typedef unsigned long unsigned32;
  495. typedef unsigned short unsigned16;
  496. typedef unsigned char unsigned8;
  497. typedef unsigned char byte;
  498. #define CLOCK_SEQ_LAST 0x3FFF
  499. #define RAND_MASK CLOCK_SEQ_LAST
  500. typedef struct _uuid_t {
  501. unsigned32 time_low;
  502. unsigned16 time_mid;
  503. unsigned16 time_hi_and_version;
  504. unsigned8 clock_seq_hi_and_reserved;
  505. unsigned8 clock_seq_low;
  506. byte node[6];
  507. } uuid_t;
  508. typedef struct _unsigned64_t {
  509. unsigned32 lo;
  510. unsigned32 hi;
  511. } unsigned64_t;
  512. /*
  513. ** Add two unsigned 64-bit long integers.
  514. */
  515. #define ADD_64b_2_64b(A, B, sum) \
  516. { \
  517. if (!(((A)->lo & 0x80000000UL) ^ ((B)->lo & 0x80000000UL))) {
  518. \
  519. if (((A)->lo&0x80000000UL)) { \
  520. (sum)->lo = (A)->lo + (B)->lo; \
  521. (sum)->hi = (A)->hi + (B)->hi + 1; \
  522. } \
  523. else { \
  524. (sum)->lo = (A)->lo + (B)->lo; \
  525. (sum)->hi = (A)->hi + (B)->hi; \
  526. Leach, Salz expires July 1997 [Page 13]
  527. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  528. } \
  529. } \
  530. else { \
  531. (sum)->lo = (A)->lo + (B)->lo; \
  532. (sum)->hi = (A)->hi + (B)->hi; \
  533. if (!((sum)->lo&0x80000000UL)) (sum)->hi++; \
  534. } \
  535. }
  536. /*
  537. ** Add a 16-bit unsigned integer to a 64-bit unsigned integer.
  538. */
  539. #define ADD_16b_2_64b(A, B, sum) \
  540. { \
  541. (sum)->hi = (B)->hi; \
  542. if ((B)->lo & 0x80000000UL) { \
  543. (sum)->lo = (*A) + (B)->lo; \
  544. if (!((sum)->lo & 0x80000000UL)) (sum)->hi++; \
  545. } \
  546. else \
  547. (sum)->lo = (*A) + (B)->lo; \
  548. }
  549. /*
  550. ** Global variables.
  551. */
  552. static unsigned64_t time_last;
  553. static unsigned16 clock_seq;
  554. static void
  555. mult32(unsigned32 u, unsigned32 v, unsigned64_t *result)
  556. {
  557. /* Following the notation in Knuth, Vol. 2. */
  558. unsigned32 uuid1, uuid2, v1, v2, temp;
  559. uuid1 = u >> 16;
  560. uuid2 = u & 0xFFFF;
  561. v1 = v >> 16;
  562. v2 = v & 0xFFFF;
  563. temp = uuid2 * v2;
  564. result->lo = temp & 0xFFFF;
  565. temp = uuid1 * v2 + (temp >> 16);
  566. result->hi = temp >> 16;
  567. temp = uuid2 * v1 + (temp & 0xFFFF);
  568. result->lo += (temp & 0xFFFF) << 16;
  569. result->hi += uuid1 * v1 + (temp >> 16);
  570. }
  571. static void
  572. get_system_time(unsigned64_t *uuid_time)
  573. {
  574. struct timeval tp;
  575. unsigned64_t utc, usecs, os_basetime_diff;
  576. Leach, Salz expires July 1997 [Page 14]
  577. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  578. gettimeofday(&tp, (struct timezone *)0);
  579. mult32((long)tp.tv_sec, 10000000, &utc);
  580. mult32((long)tp.tv_usec, 10, &usecs);
  581. ADD_64b_2_64b(&usecs, &utc, &utc);
  582. /* Offset between UUID formatted times and Unix formatted times.
  583. * UUID UTC base time is October 15, 1582.
  584. * Unix base time is January 1, 1970. */
  585. os_basetime_diff.lo = 0x13814000;
  586. os_basetime_diff.hi = 0x01B21DD2;
  587. ADD_64b_2_64b(&utc, &os_basetime_diff, uuid_time);
  588. }
  589. /*
  590. ** See "The Multiple Prime Random Number Generator" by Alexander
  591. ** Hass pp. 368-381, ACM Transactions on Mathematical Software,
  592. ** 12/87.
  593. */
  594. static unsigned32 rand_m;
  595. static unsigned32 rand_ia;
  596. static unsigned32 rand_ib;
  597. static unsigned32 rand_irand;
  598. static void
  599. true_random_init(void)
  600. {
  601. unsigned64_t t;
  602. unsigned16 seed;
  603. /* Generating our 'seed' value Start with the current time, but,
  604. * since the resolution of clocks is system hardware dependent and
  605. * most likely coarser than our resolution (10 usec) we 'mixup' the
  606. * bits by xor'ing all the bits together. This will have the effect
  607. * of involving all of the bits in the determination of the seed
  608. * value while remaining system independent. Then for good measure
  609. * to ensure a unique seed when there are multiple processes
  610. * creating UUIDs on a system, we add in the PID.
  611. */
  612. rand_m = 971;
  613. rand_ia = 11113;
  614. rand_ib = 104322;
  615. rand_irand = 4181;
  616. get_system_time(&t);
  617. seed = t.lo & 0xFFFF;
  618. seed ^= (t.lo >> 16) & 0xFFFF;
  619. seed ^= t.hi & 0xFFFF;
  620. seed ^= (t.hi >> 16) & 0xFFFF;
  621. rand_irand += seed + getpid();
  622. }
  623. static unsigned16
  624. true_random(void)
  625. {
  626. if ((rand_m += 7) >= 9973)
  627. Leach, Salz expires July 1997 [Page 15]
  628. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  629. rand_m -= 9871;
  630. if ((rand_ia += 1907) >= 99991)
  631. rand_ia -= 89989;
  632. if ((rand_ib += 73939) >= 224729)
  633. rand_ib -= 96233;
  634. rand_irand = (rand_irand * rand_m) + rand_ia + rand_ib;
  635. return (rand_irand >> 16) ^ (rand_irand & RAND_MASK);
  636. }
  637. /*
  638. ** Startup initialization routine for the UUID module.
  639. */
  640. void
  641. uuid_init(void)
  642. {
  643. true_random_init();
  644. get_system_time(&time_last);
  645. #ifdef NONVOLATILE_CLOCK
  646. clock_seq = read_clock();
  647. #else
  648. clock_seq = true_random();
  649. #endif
  650. }
  651. static int
  652. time_cmp(unsigned64_t *time1, unsigned64_t *time2)
  653. {
  654. if (time1->hi < time2->hi) return -1;
  655. if (time1->hi > time2->hi) return 1;
  656. if (time1->lo < time2->lo) return -1;
  657. if (time1->lo > time2->lo) return 1;
  658. return 0;
  659. }
  660. static void new_clock_seq(void)
  661. {
  662. clock_seq = (clock_seq + 1) % (CLOCK_SEQ_LAST + 1);
  663. if (clock_seq == 0) clock_seq = 1;
  664. #ifdef NONVOLATILE_CLOCK
  665. write_clock(clock_seq);
  666. #endif
  667. }
  668. void uuid_create(uuid_t *uuid)
  669. {
  670. static unsigned64_t time_now;
  671. static unsigned16 time_adjust;
  672. byte eaddr[6];
  673. int got_no_time = 0;
  674. get_ieee_node_identifier(&eaddr); /* TO BE PROVIDED */
  675. do {
  676. get_system_time(&time_now);
  677. Leach, Salz expires July 1997 [Page 16]
  678. Internet-Draft UUIDs and GUIDs (DRAFT) 02/24/97
  679. switch (time_cmp(&time_now, &time_last)) {
  680. case -1:
  681. /* Time went backwards. */
  682. new_clock_seq();
  683. time_adjust = 0;
  684. break;
  685. case 1:
  686. time_adjust = 0;
  687. break;
  688. default:
  689. if (time_adjust == 0x7FFF)
  690. /* We're going too fast for our clock; spin. */
  691. got_no_time = 1;
  692. else
  693. time_adjust++;
  694. break;
  695. }
  696. } while (got_no_time);
  697. time_last.lo = time_now.lo;
  698. time_last.hi = time_now.hi;
  699. if (time_adjust != 0) {
  700. ADD_16b_2_64b(&time_adjust, &time_now, &time_now);
  701. }
  702. /* Construct a uuid with the information we've gathered
  703. * plus a few constants. */
  704. uuid->time_low = time_now.lo;
  705. uuid->time_mid = time_now.hi & 0x0000FFFF;
  706. uuid->time_hi_and_version = (time_now.hi & 0x0FFF0000) >> 16;
  707. uuid->time_hi_and_version |= (1 << 12);
  708. uuid->clock_seq_low = clock_seq & 0xFF;
  709. uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8;
  710. uuid->clock_seq_hi_and_reserved |= 0x80;
  711. memcpy(uuid->node, &eaddr, sizeof uuid->node);
  712. }
  713. Leach, Salz expires July 1997 [Page 17]