aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2009-02-11 22:51:25 +0000
committerMike Buland <eichlan@xagasoft.com>2009-02-11 22:51:25 +0000
commit3f958097632256329cdbaf2219e2ba15325e9c52 (patch)
treee7616f7db3709d68ae51d6da0ef8ce44600bd33f
parentf4b191f0ea396b58465bfba40749977780a3af58 (diff)
downloadlibbu++-3f958097632256329cdbaf2219e2ba15325e9c52.tar.gz
libbu++-3f958097632256329cdbaf2219e2ba15325e9c52.tar.bz2
libbu++-3f958097632256329cdbaf2219e2ba15325e9c52.tar.xz
libbu++-3f958097632256329cdbaf2219e2ba15325e9c52.zip
Hey, formatter, awesome, and look at that...I'm adding uuid support.
-rw-r--r--misc/rfc41221928
-rw-r--r--src/formatter.cpp76
-rw-r--r--src/formatter.h71
-rw-r--r--src/tests/stdstream.cpp31
-rw-r--r--src/uuid.cpp18
-rw-r--r--src/uuid.h25
6 files changed, 2123 insertions, 26 deletions
diff --git a/misc/rfc4122 b/misc/rfc4122
new file mode 100644
index 0000000..5c5a8a5
--- /dev/null
+++ b/misc/rfc4122
@@ -0,0 +1,1928 @@
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4<head>
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6 <meta name="robots" content="index,follow" />
7 <meta name="creator" content="rfcmarkup version 1.73" />
8 <link rel="icon" href="/images/rfc.png" type="image/png" />
9 <link rel="shortcut icon" href="/images/rfc.png" type="image/png" />
10 <title>RFC 4122 - A Universally Unique IDentifier (UUID) URN Namespace</title>
11
12 <style type="text/css">
13 body {
14 margin: 0px 8px;
15 font-size: 1em;
16 }
17 h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
18 font-weight: bold;
19 line-height: 0pt;
20 display: inline;
21 white-space: pre;
22 font-family: monospace;
23 font-size: 1em;
24 font-weight: bold;
25 }
26 pre {
27 font-size: 1em;
28 margin-top: 0px;
29 margin-bottom: 0px;
30 }
31 .pre {
32 white-space: pre;
33 font-family: monospace;
34 }
35 .header{
36 font-weight: bold;
37 }
38 .newpage {
39 page-break-before: always;
40 }
41 .invisible {
42 text-decoration: none;
43 color: white;
44 }
45 @media print {
46 body {
47 font-size: 10.5pt;
48 }
49 h1, h2, h3, h4, h5, h6 {
50 font-size: 10.5pt;
51 }
52
53 a:link, a:visited {
54 color: inherit;
55 text-decoration: none;
56 }
57 .noprint {
58 display: none;
59 }
60 }
61 @media screen {
62 .grey, .grey a:link, .grey a:visited {
63 color: #777;
64 }
65 .docinfo {
66 background-color: #EEE;
67 }
68 .top {
69 border-top: 7px solid #EEE;
70 }
71 .bgwhite { background-color: white; }
72 .bgred { background-color: #F44; }
73 .bggrey { background-color: #666; }
74 .bgbrown { background-color: #840; }
75 .bgorange { background-color: #FA0; }
76 .bgyellow { background-color: #EE0; }
77 .bgmagenta{ background-color: #F4F; }
78 .bgblue { background-color: #66F; }
79 .bgcyan { background-color: #4DD; }
80 .bggreen { background-color: #4F4; }
81
82 .legend { font-size: 90%; }
83 .cplate { font-size: 70%; border: solid grey 1px; }
84 }
85 </style>
86
87 <script type="text/javascript"><!--
88 function addHeaderTags() {
89 var spans = document.getElementsByTagName("span");
90 for (var i=0; i < spans.length; i++) {
91 var elem = spans[i];
92 if (elem) {
93 var level = elem.getAttribute("class");
94 if (level == "h1" || level == "h2" || level == "h3" || level == "h4" || level == "h5" || level == "h6") {
95 elem.innerHTML = "<"+level+">"+elem.innerHTML+"</"+level+">";
96 }
97 }
98 }
99 }
100 var legend_html = "Colour legend:<br /> <table> <tr><td>Unknown:</td> <td><span class='cplate bgwhite'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Draft:</td> <td><span class='cplate bgred'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Informational:</td> <td><span class='cplate bgorange'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Experimental:</td> <td><span class='cplate bgyellow'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Best Common Practice:</td><td><span class='cplate bgmagenta'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Proposed Standard:</td><td><span class='cplate bgblue'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Draft Standard:</td> <td><span class='cplate bgcyan'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Standard:</td> <td><span class='cplate bggreen'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Historic:</td> <td><span class='cplate bggrey'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> <tr><td>Obsolete:</td> <td><span class='cplate bgbrown'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> </table>";
101 function showElem(id) {
102 var elem = document.getElementById(id);
103 elem.innerHTML = eval(id+"_html");
104 elem.style.visibility='visible';
105 }
106 function hideElem(id) {
107 var elem = document.getElementById(id);
108 elem.style.visibility='hidden';
109 elem.innerHTML = "";
110 }
111 // -->
112 </script>
113</head>
114<body onload="addHeaderTags()">
115 <div style="height: 13px;">
116 <div onmouseover="this.style.cursor='pointer';"
117 onclick="showElem('legend');"
118 onmouseout="hideElem('legend')"
119 style="height: 6px; position: absolute;"
120 class="pre noprint docinfo bgblue"
121 title="Click for colour legend." > </div>
122 <div id="legend"
123 class="docinfo noprint pre legend"
124 style="position:absolute; top: 4px; left: 4ex; visibility:hidden; background-color: white; padding: 4px 9px 5px 7px; border: solid #345 1px; "
125 onmouseover="showElem('legend');"
126 onmouseout="hideElem('legend');">
127 </div>
128 </div>
129<span class="pre noprint docinfo top">[<a href="../html/" title="Document search and retrieval page">RFCs/IDs</a>] [<a href="/rfc/rfc4122.txt" title="Plaintext version of this document">Plain Text</a>] [From <a href="draft-mealling-uuid-urn">draft-mealling-uuid-urn</a>] </span><br />
130<span class="pre noprint docinfo"> </span><br />
131<span class="pre noprint docinfo"> PROPOSED STANDARD</span><br />
132<span class="pre noprint docinfo"> <a href="http://www.rfc-editor.org/errata_search.php?rfc=4122">Errata</a></span><br />
133<pre>
134Network Working Group P. Leach
135Request for Comments: 4122 Microsoft
136Category: Standards Track M. Mealling
137 Refactored Networks, LLC
138 R. Salz
139 DataPower Technology, Inc.
140 July 2005
141
142
143 <span class="h1">A Universally Unique IDentifier (UUID) URN Namespace</span>
144
145Status of This Memo
146
147 This document specifies an Internet standards track protocol for the
148 Internet community, and requests discussion and suggestions for
149 improvements. Please refer to the current edition of the "Internet
150 Official Protocol Standards" (STD 1) for the standardization state
151 and status of this protocol. Distribution of this memo is unlimited.
152
153Copyright Notice
154
155 Copyright (C) The Internet Society (2005).
156
157Abstract
158
159 This specification defines a Uniform Resource Name namespace for
160 UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally
161 Unique IDentifier). A UUID is 128 bits long, and can guarantee
162 uniqueness across space and time. UUIDs were originally used in the
163 Apollo Network Computing System and later in the Open Software
164 Foundation's (OSF) Distributed Computing Environment (DCE), and then
165 in Microsoft Windows platforms.
166
167 This specification is derived from the DCE specification with the
168 kind permission of the OSF (now known as The Open Group).
169 Information from earlier versions of the DCE specification have been
170 incorporated into this document.
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185<span class="grey">Leach, et al. Standards Track [Page 1]</span>
186</pre><pre class='newpage'><a name="page-2" id="page-2" href="#page-2" class="invisible"> </a>
187<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
188
189
190Table of Contents
191
192 <a href="#section-1">1</a>. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-2">2</a>
193 <a href="#section-2">2</a>. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-3">3</a>
194 <a href="#section-3">3</a>. Namespace Registration Template . . . . . . . . . . . . . . . <a href="#page-3">3</a>
195 <a href="#section-4">4</a>. Specification . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-5">5</a>
196 <a href="#section-4.1">4.1</a>. Format. . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-5">5</a>
197 <a href="#section-4.1.1">4.1.1</a>. Variant. . . . . . . . . . . . . . . . . . . . . . <a href="#page-6">6</a>
198 <a href="#section-4.1.2">4.1.2</a>. Layout and Byte Order. . . . . . . . . . . . . . . <a href="#page-6">6</a>
199 <a href="#section-4.1.3">4.1.3</a>. Version. . . . . . . . . . . . . . . . . . . . . . <a href="#page-7">7</a>
200 <a href="#section-4.1.4">4.1.4</a>. Timestamp. . . . . . . . . . . . . . . . . . . . . <a href="#page-8">8</a>
201 <a href="#section-4.1.5">4.1.5</a>. Clock Sequence . . . . . . . . . . . . . . . . . . <a href="#page-8">8</a>
202 <a href="#section-4.1.6">4.1.6</a>. Node . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-9">9</a>
203 <a href="#section-4.1.7">4.1.7</a>. Nil UUID . . . . . . . . . . . . . . . . . . . . . <a href="#page-9">9</a>
204 <a href="#section-4.2">4.2</a>. Algorithms for Creating a Time-Based UUID . . . . . . . . <a href="#page-9">9</a>
205 <a href="#section-4.2.1">4.2.1</a>. Basic Algorithm. . . . . . . . . . . . . . . . . . <a href="#page-10">10</a>
206 <a href="#section-4.2.2">4.2.2</a>. Generation Details . . . . . . . . . . . . . . . . <a href="#page-12">12</a>
207 <a href="#section-4.3">4.3</a>. Algorithm for Creating a Name-Based UUID. . . . . . . . . <a href="#page-13">13</a>
208 4.4. Algorithms for Creating a UUID from Truly Random or
209 Pseudo-Random Numbers . . . . . . . . . . . . . . . . . . <a href="#page-14">14</a>
210 <a href="#section-4.5">4.5</a>. Node IDs that Do Not Identify the Host. . . . . . . . . . <a href="#page-15">15</a>
211 <a href="#section-5">5</a>. Community Considerations . . . . . . . . . . . . . . . . . . . <a href="#page-15">15</a>
212 <a href="#section-6">6</a>. Security Considerations . . . . . . . . . . . . . . . . . . . <a href="#page-16">16</a>
213 <a href="#section-7">7</a>. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-16">16</a>
214 <a href="#section-8">8</a>. Normative References . . . . . . . . . . . . . . . . . . . . . <a href="#page-16">16</a>
215 <a href="#appendix-A">A</a>. <a href="#appendix-A">Appendix A</a> - Sample Implementation . . . . . . . . . . . . . . <a href="#page-18">18</a>
216 <a href="#appendix-B">B</a>. <a href="#appendix-B">Appendix B</a> - Sample Output of utest . . . . . . . . . . . . . <a href="#page-29">29</a>
217 <a href="#appendix-C">C</a>. <a href="#appendix-C">Appendix C</a> - Some Name Space IDs . . . . . . . . . . . . . . . <a href="#page-30">30</a>
218
219<span class="h2"><a name="section-1">1</a>. Introduction</span>
220
221 This specification defines a Uniform Resource Name namespace for
222 UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally
223 Unique IDentifier). A UUID is 128 bits long, and requires no central
224 registration process.
225
226 The information here is meant to be a concise guide for those wishing
227 to implement services using UUIDs as URNs. Nothing in this document
228 should be construed to override the DCE standards that defined UUIDs.
229
230 There is an ITU-T Recommendation and ISO/IEC Standard [<a href="#ref-3" title='"Procedures for the operation of OSI Registration Authorities: Generation and registration of Universally Unique Identifiers (UUIDs) and their use as ASN.1 Object Identifier components"'>3</a>] that are
231 derived from earlier versions of this document. Both sets of
232 specifications have been aligned, and are fully technically
233 compatible. In addition, a global registration function is being
234 provided by the Telecommunications Standardisation Bureau of ITU-T;
235 for details see &lt;<a href="http://www.itu.int/ITU-T/asn1/uuid.html">http://www.itu.int/ITU-T/asn1/uuid.html</a>&gt;.
236
237
238
239
240
241<span class="grey">Leach, et al. Standards Track [Page 2]</span>
242</pre><pre class='newpage'><a name="page-3" id="page-3" href="#page-3" class="invisible"> </a>
243<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
244
245
246<span class="h2"><a name="section-2">2</a>. Motivation</span>
247
248 One of the main reasons for using UUIDs is that no centralized
249 authority is required to administer them (although one format uses
250 IEEE 802 node identifiers, others do not). As a result, generation
251 on demand can be completely automated, and used for a variety of
252 purposes. The UUID generation algorithm described here supports very
253 high allocation rates of up to 10 million per second per machine if
254 necessary, so that they could even be used as transaction IDs.
255
256 UUIDs are of a fixed size (128 bits) which is reasonably small
257 compared to other alternatives. This lends itself well to sorting,
258 ordering, and hashing of all sorts, storing in databases, simple
259 allocation, and ease of programming in general.
260
261 Since UUIDs are unique and persistent, they make excellent Uniform
262 Resource Names. The unique ability to generate a new UUID without a
263 registration process allows for UUIDs to be one of the URNs with the
264 lowest minting cost.
265
266<span class="h2"><a name="section-3">3</a>. Namespace Registration Template</span>
267
268 Namespace ID: UUID
269 Registration Information:
270 Registration date: 2003-10-01
271
272 Declared registrant of the namespace:
273 JTC 1/SC6 (ASN.1 Rapporteur Group)
274
275 Declaration of syntactic structure:
276 A UUID is an identifier that is unique across both space and time,
277 with respect to the space of all UUIDs. Since a UUID is a fixed
278 size and contains a time field, it is possible for values to
279 rollover (around A.D. 3400, depending on the specific algorithm
280 used). A UUID can be used for multiple purposes, from tagging
281 objects with an extremely short lifetime, to reliably identifying
282 very persistent objects across a network.
283
284 The internal representation of a UUID is a specific sequence of
285 bits in memory, as described in <a href="#section-4">Section 4</a>. To accurately
286 represent a UUID as a URN, it is necessary to convert the bit
287 sequence to a string representation.
288
289 Each field is treated as an integer and has its value printed as a
290 zero-filled hexadecimal digit string with the most significant
291 digit first. The hexadecimal values "a" through "f" are output as
292 lower case characters and are case insensitive on input.
293
294
295
296
297<span class="grey">Leach, et al. Standards Track [Page 3]</span>
298</pre><pre class='newpage'><a name="page-4" id="page-4" href="#page-4" class="invisible"> </a>
299<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
300
301
302 The formal definition of the UUID string representation is
303 provided by the following ABNF [<a href="#ref-7" title='"Augmented BNF for Syntax Specifications: ABNF"'>7</a>]:
304
305 UUID = time-low "-" time-mid "-"
306 time-high-and-version "-"
307 clock-seq-and-reserved
308 clock-seq-low "-" node
309 time-low = 4hexOctet
310 time-mid = 2hexOctet
311 time-high-and-version = 2hexOctet
312 clock-seq-and-reserved = hexOctet
313 clock-seq-low = hexOctet
314 node = 6hexOctet
315 hexOctet = hexDigit hexDigit
316 hexDigit =
317 "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
318 "a" / "b" / "c" / "d" / "e" / "f" /
319 "A" / "B" / "C" / "D" / "E" / "F"
320
321 The following is an example of the string representation of a UUID as
322 a URN:
323
324 urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6
325
326 Relevant ancillary documentation:
327 [<a href="#ref-1" title='"Network Computing Architecture"'>1</a>][2]
328 Identifier uniqueness considerations:
329 This document specifies three algorithms to generate UUIDs: the
330 first leverages the unique values of 802 MAC addresses to
331 guarantee uniqueness, the second uses pseudo-random number
332 generators, and the third uses cryptographic hashing and
333 application-provided text strings. As a result, the UUIDs
334 generated according to the mechanisms here will be unique from all
335 other UUIDs that have been or will be assigned.
336
337 Identifier persistence considerations:
338 UUIDs are inherently very difficult to resolve in a global sense.
339 This, coupled with the fact that UUIDs are temporally unique
340 within their spatial context, ensures that UUIDs will remain as
341 persistent as possible.
342
343 Process of identifier assignment:
344 Generating a UUID does not require that a registration authority
345 be contacted. One algorithm requires a unique value over space
346 for each generator. This value is typically an IEEE 802 MAC
347 address, usually already available on network-connected hosts.
348 The address can be assigned from an address block obtained from
349 the IEEE registration authority. If no such address is available,
350
351
352
353<span class="grey">Leach, et al. Standards Track [Page 4]</span>
354</pre><pre class='newpage'><a name="page-5" id="page-5" href="#page-5" class="invisible"> </a>
355<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
356
357
358 or privacy concerns make its use undesirable, <a href="#section-4.5">Section 4.5</a>
359 specifies two alternatives. Another approach is to use version 3
360 or version 4 UUIDs as defined below.
361
362 Process for identifier resolution:
363 Since UUIDs are not globally resolvable, this is not applicable.
364
365 Rules for Lexical Equivalence:
366 Consider each field of the UUID to be an unsigned integer as shown
367 in the table in section <a href="#section-4.1.2">Section 4.1.2</a>. Then, to compare a pair of
368 UUIDs, arithmetically compare the corresponding fields from each
369 UUID in order of significance and according to their data type.
370 Two UUIDs are equal if and only if all the corresponding fields
371 are equal.
372
373 As an implementation note, equality comparison can be performed on
374 many systems by doing the appropriate byte-order canonicalization,
375 and then treating the two UUIDs as 128-bit unsigned integers.
376
377 UUIDs, as defined in this document, can also be ordered
378 lexicographically. For a pair of UUIDs, the first one follows the
379 second if the most significant field in which the UUIDs differ is
380 greater for the first UUID. The second precedes the first if the
381 most significant field in which the UUIDs differ is greater for
382 the second UUID.
383
384 Conformance with URN Syntax:
385 The string representation of a UUID is fully compatible with the
386 URN syntax. When converting from a bit-oriented, in-memory
387 representation of a UUID into a URN, care must be taken to
388 strictly adhere to the byte order issues mentioned in the string
389 representation section.
390
391 Validation mechanism:
392 Apart from determining whether the timestamp portion of the UUID
393 is in the future and therefore not yet assignable, there is no
394 mechanism for determining whether a UUID is 'valid'.
395
396 Scope:
397 UUIDs are global in scope.
398
399<span class="h2"><a name="section-4">4</a>. Specification</span>
400
401<span class="h3"><a name="section-4.1">4.1</a>. Format</span>
402
403 The UUID format is 16 octets; some bits of the eight octet variant
404 field specified below determine finer structure.
405
406
407
408
409<span class="grey">Leach, et al. Standards Track [Page 5]</span>
410</pre><pre class='newpage'><a name="page-6" id="page-6" href="#page-6" class="invisible"> </a>
411<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
412
413
414<span class="h4"><a name="section-4.1.1">4.1.1</a>. Variant</span>
415
416 The variant field determines the layout of the UUID. That is, the
417 interpretation of all other bits in the UUID depends on the setting
418 of the bits in the variant field. As such, it could more accurately
419 be called a type field; we retain the original term for
420 compatibility. The variant field consists of a variable number of
421 the most significant bits of octet 8 of the UUID.
422
423 The following table lists the contents of the variant field, where
424 the letter "x" indicates a "don't-care" value.
425
426 Msb0 Msb1 Msb2 Description
427
428 0 x x Reserved, NCS backward compatibility.
429
430 1 0 x The variant specified in this document.
431
432 1 1 0 Reserved, Microsoft Corporation backward
433 compatibility
434
435 1 1 1 Reserved for future definition.
436
437 Interoperability, in any form, with variants other than the one
438 defined here is not guaranteed, and is not likely to be an issue in
439 practice.
440
441<span class="h4"><a name="section-4.1.2">4.1.2</a>. Layout and Byte Order</span>
442
443 To minimize confusion about bit assignments within octets, the UUID
444 record definition is defined only in terms of fields that are
445 integral numbers of octets. The fields are presented with the most
446 significant one first.
447
448 Field Data Type Octet Note
449 #
450
451 time_low unsigned 32 0-3 The low field of the
452 bit integer timestamp
453
454 time_mid unsigned 16 4-5 The middle field of the
455 bit integer timestamp
456
457 time_hi_and_version unsigned 16 6-7 The high field of the
458 bit integer timestamp multiplexed
459 with the version number
460
461
462
463
464
465<span class="grey">Leach, et al. Standards Track [Page 6]</span>
466</pre><pre class='newpage'><a name="page-7" id="page-7" href="#page-7" class="invisible"> </a>
467<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
468
469
470 clock_seq_hi_and_rese unsigned 8 8 The high field of the
471 rved bit integer clock sequence
472 multiplexed with the
473 variant
474
475 clock_seq_low unsigned 8 9 The low field of the
476 bit integer clock sequence
477
478 node unsigned 48 10-15 The spatially unique
479 bit integer node identifier
480
481 In the absence of explicit application or presentation protocol
482 specification to the contrary, a UUID is encoded as a 128-bit object,
483 as follows:
484
485 The fields are encoded as 16 octets, with the sizes and order of the
486 fields defined above, and with each field encoded with the Most
487 Significant Byte first (known as network byte order). Note that the
488 field names, particularly for multiplexed fields, follow historical
489 practice.
490
491 0 1 2 3
492 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
493 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
494 | time_low |
495 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
496 | time_mid | time_hi_and_version |
497 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
498 |clk_seq_hi_res | clk_seq_low | node (0-1) |
499 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
500 | node (2-5) |
501 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
502
503<span class="h4"><a name="section-4.1.3">4.1.3</a>. Version</span>
504
505 The version number is in the most significant 4 bits of the time
506 stamp (bits 4 through 7 of the time_hi_and_version field).
507
508 The following table lists the currently-defined versions for this
509 UUID variant.
510
511 Msb0 Msb1 Msb2 Msb3 Version Description
512
513 0 0 0 1 1 The time-based version
514 specified in this document.
515
516 0 0 1 0 2 DCE Security version, with
517 embedded POSIX UIDs.
518
519
520
521<span class="grey">Leach, et al. Standards Track [Page 7]</span>
522</pre><pre class='newpage'><a name="page-8" id="page-8" href="#page-8" class="invisible"> </a>
523<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
524
525
526 0 0 1 1 3 The name-based version
527 specified in this document
528 that uses MD5 hashing.
529
530 0 1 0 0 4 The randomly or pseudo-
531 randomly generated version
532 specified in this document.
533
534 0 1 0 1 5 The name-based version
535 specified in this document
536 that uses SHA-1 hashing.
537
538 The version is more accurately a sub-type; again, we retain the term
539 for compatibility.
540
541<span class="h4"><a name="section-4.1.4">4.1.4</a>. Timestamp</span>
542
543 The timestamp is a 60-bit value. For UUID version 1, this is
544 represented by Coordinated Universal Time (UTC) as a count of 100-
545 nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of
546 Gregorian reform to the Christian calendar).
547
548 For systems that do not have UTC available, but do have the local
549 time, they may use that instead of UTC, as long as they do so
550 consistently throughout the system. However, this is not recommended
551 since generating the UTC from local time only needs a time zone
552 offset.
553
554 For UUID version 3 or 5, the timestamp is a 60-bit value constructed
555 from a name as described in <a href="#section-4.3">Section 4.3</a>.
556
557 For UUID version 4, the timestamp is a randomly or pseudo-randomly
558 generated 60-bit value, as described in <a href="#section-4.4">Section 4.4</a>.
559
560<span class="h4"><a name="section-4.1.5">4.1.5</a>. Clock Sequence</span>
561
562 For UUID version 1, the clock sequence is used to help avoid
563 duplicates that could arise when the clock is set backwards in time
564 or if the node ID changes.
565
566 If the clock is set backwards, or might have been set backwards
567 (e.g., while the system was powered off), and the UUID generator can
568 not be sure that no UUIDs were generated with timestamps larger than
569 the value to which the clock was set, then the clock sequence has to
570 be changed. If the previous value of the clock sequence is known, it
571 can just be incremented; otherwise it should be set to a random or
572 high-quality pseudo-random value.
573
574
575
576
577<span class="grey">Leach, et al. Standards Track [Page 8]</span>
578</pre><pre class='newpage'><a name="page-9" id="page-9" href="#page-9" class="invisible"> </a>
579<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
580
581
582 Similarly, if the node ID changes (e.g., because a network card has
583 been moved between machines), setting the clock sequence to a random
584 number minimizes the probability of a duplicate due to slight
585 differences in the clock settings of the machines. If the value of
586 clock sequence associated with the changed node ID were known, then
587 the clock sequence could just be incremented, but that is unlikely.
588
589 The clock sequence MUST be originally (i.e., once in the lifetime of
590 a system) initialized to a random number to minimize the correlation
591 across systems. This provides maximum protection against node
592 identifiers that may move or switch from system to system rapidly.
593 The initial value MUST NOT be correlated to the node identifier.
594
595 For UUID version 3 or 5, the clock sequence is a 14-bit value
596 constructed from a name as described in <a href="#section-4.3">Section 4.3</a>.
597
598 For UUID version 4, clock sequence is a randomly or pseudo-randomly
599 generated 14-bit value as described in <a href="#section-4.4">Section 4.4</a>.
600
601<span class="h4"><a name="section-4.1.6">4.1.6</a>. Node</span>
602
603 For UUID version 1, the node field consists of an IEEE 802 MAC
604 address, usually the host address. For systems with multiple IEEE
605 802 addresses, any available one can be used. The lowest addressed
606 octet (octet number 10) contains the global/local bit and the
607 unicast/multicast bit, and is the first octet of the address
608 transmitted on an 802.3 LAN.
609
610 For systems with no IEEE address, a randomly or pseudo-randomly
611 generated value may be used; see <a href="#section-4.5">Section 4.5</a>. The multicast bit must
612 be set in such addresses, in order that they will never conflict with
613 addresses obtained from network cards.
614
615 For UUID version 3 or 5, the node field is a 48-bit value constructed
616 from a name as described in <a href="#section-4.3">Section 4.3</a>.
617
618 For UUID version 4, the node field is a randomly or pseudo-randomly
619 generated 48-bit value as described in <a href="#section-4.4">Section 4.4</a>.
620
621<span class="h4"><a name="section-4.1.7">4.1.7</a>. Nil UUID</span>
622
623 The nil UUID is special form of UUID that is specified to have all
624 128 bits set to zero.
625
626<span class="h3"><a name="section-4.2">4.2</a>. Algorithms for Creating a Time-Based UUID</span>
627
628 Various aspects of the algorithm for creating a version 1 UUID are
629 discussed in the following sections.
630
631
632
633<span class="grey">Leach, et al. Standards Track [Page 9]</span>
634</pre><pre class='newpage'><a name="page-10" id="page-10" href="#page-10" class="invisible"> </a>
635<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
636
637
638<span class="h4"><a name="section-4.2.1">4.2.1</a>. Basic Algorithm</span>
639
640 The following algorithm is simple, correct, and inefficient:
641
642 o Obtain a system-wide global lock
643
644 o From a system-wide shared stable store (e.g., a file), read the
645 UUID generator state: the values of the timestamp, clock sequence,
646 and node ID used to generate the last UUID.
647
648 o Get the current time as a 60-bit count of 100-nanosecond intervals
649 since 00:00:00.00, 15 October 1582.
650
651 o Get the current node ID.
652
653 o If the state was unavailable (e.g., non-existent or corrupted), or
654 the saved node ID is different than the current node ID, generate
655 a random clock sequence value.
656
657 o If the state was available, but the saved timestamp is later than
658 the current timestamp, increment the clock sequence value.
659
660 o Save the state (current timestamp, clock sequence, and node ID)
661 back to the stable store.
662
663 o Release the global lock.
664
665 o Format a UUID from the current timestamp, clock sequence, and node
666 ID values according to the steps in <a href="#section-4.2.2">Section 4.2.2</a>.
667
668 If UUIDs do not need to be frequently generated, the above algorithm
669 may be perfectly adequate. For higher performance requirements,
670 however, issues with the basic algorithm include:
671
672 o Reading the state from stable storage each time is inefficient.
673
674 o The resolution of the system clock may not be 100-nanoseconds.
675
676 o Writing the state to stable storage each time is inefficient.
677
678 o Sharing the state across process boundaries may be inefficient.
679
680 Each of these issues can be addressed in a modular fashion by local
681 improvements in the functions that read and write the state and read
682 the clock. We address each of them in turn in the following
683 sections.
684
685
686
687
688
689<span class="grey">Leach, et al. Standards Track [Page 10]</span>
690</pre><pre class='newpage'><a name="page-11" id="page-11" href="#page-11" class="invisible"> </a>
691<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
692
693
694<span class="h5"><a name="section-4.2.1.1">4.2.1.1</a>. Reading Stable Storage</span>
695
696 The state only needs to be read from stable storage once at boot
697 time, if it is read into a system-wide shared volatile store (and
698 updated whenever the stable store is updated).
699
700 If an implementation does not have any stable store available, then
701 it can always say that the values were unavailable. This is the
702 least desirable implementation because it will increase the frequency
703 of creation of new clock sequence numbers, which increases the
704 probability of duplicates.
705
706 If the node ID can never change (e.g., the net card is inseparable
707 from the system), or if any change also reinitializes the clock
708 sequence to a random value, then instead of keeping it in stable
709 store, the current node ID may be returned.
710
711<span class="h5"><a name="section-4.2.1.2">4.2.1.2</a>. System Clock Resolution</span>
712
713 The timestamp is generated from the system time, whose resolution may
714 be less than the resolution of the UUID timestamp.
715
716 If UUIDs do not need to be frequently generated, the timestamp can
717 simply be the system time multiplied by the number of 100-nanosecond
718 intervals per system time interval.
719
720 If a system overruns the generator by requesting too many UUIDs
721 within a single system time interval, the UUID service MUST either
722 return an error, or stall the UUID generator until the system clock
723 catches up.
724
725 A high resolution timestamp can be simulated by keeping a count of
726 the number of UUIDs that have been generated with the same value of
727 the system time, and using it to construct the low order bits of the
728 timestamp. The count will range between zero and the number of
729 100-nanosecond intervals per system time interval.
730
731 Note: If the processors overrun the UUID generation frequently,
732 additional node identifiers can be allocated to the system, which
733 will permit higher speed allocation by making multiple UUIDs
734 potentially available for each time stamp value.
735
736<span class="h5"><a name="section-4.2.1.3">4.2.1.3</a>. Writing Stable Storage</span>
737
738 The state does not always need to be written to stable store every
739 time a UUID is generated. The timestamp in the stable store can be
740 periodically set to a value larger than any yet used in a UUID. As
741 long as the generated UUIDs have timestamps less than that value, and
742
743
744
745<span class="grey">Leach, et al. Standards Track [Page 11]</span>
746</pre><pre class='newpage'><a name="page-12" id="page-12" href="#page-12" class="invisible"> </a>
747<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
748
749
750 the clock sequence and node ID remain unchanged, only the shared
751 volatile copy of the state needs to be updated. Furthermore, if the
752 timestamp value in stable store is in the future by less than the
753 typical time it takes the system to reboot, a crash will not cause a
754 reinitialization of the clock sequence.
755
756<span class="h5"><a name="section-4.2.1.4">4.2.1.4</a>. Sharing State Across Processes</span>
757
758 If it is too expensive to access shared state each time a UUID is
759 generated, then the system-wide generator can be implemented to
760 allocate a block of time stamps each time it is called; a per-
761 process generator can allocate from that block until it is exhausted.
762
763<span class="h4"><a name="section-4.2.2">4.2.2</a>. Generation Details</span>
764
765 Version 1 UUIDs are generated according to the following algorithm:
766
767 o Determine the values for the UTC-based timestamp and clock
768 sequence to be used in the UUID, as described in <a href="#section-4.2.1">Section 4.2.1</a>.
769
770 o For the purposes of this algorithm, consider the timestamp to be a
771 60-bit unsigned integer and the clock sequence to be a 14-bit
772 unsigned integer. Sequentially number the bits in a field,
773 starting with zero for the least significant bit.
774
775 o Set the time_low field equal to the least significant 32 bits
776 (bits zero through 31) of the timestamp in the same order of
777 significance.
778
779 o Set the time_mid field equal to bits 32 through 47 from the
780 timestamp in the same order of significance.
781
782 o Set the 12 least significant bits (bits zero through 11) of the
783 time_hi_and_version field equal to bits 48 through 59 from the
784 timestamp in the same order of significance.
785
786 o Set the four most significant bits (bits 12 through 15) of the
787 time_hi_and_version field to the 4-bit version number
788 corresponding to the UUID version being created, as shown in the
789 table above.
790
791 o Set the clock_seq_low field to the eight least significant bits
792 (bits zero through 7) of the clock sequence in the same order of
793 significance.
794
795
796
797
798
799
800
801<span class="grey">Leach, et al. Standards Track [Page 12]</span>
802</pre><pre class='newpage'><a name="page-13" id="page-13" href="#page-13" class="invisible"> </a>
803<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
804
805
806 o Set the 6 least significant bits (bits zero through 5) of the
807 clock_seq_hi_and_reserved field to the 6 most significant bits
808 (bits 8 through 13) of the clock sequence in the same order of
809 significance.
810
811 o Set the two most significant bits (bits 6 and 7) of the
812 clock_seq_hi_and_reserved to zero and one, respectively.
813
814 o Set the node field to the 48-bit IEEE address in the same order of
815 significance as the address.
816
817<span class="h3"><a name="section-4.3">4.3</a>. Algorithm for Creating a Name-Based UUID</span>
818
819 The version 3 or 5 UUID is meant for generating UUIDs from "names"
820 that are drawn from, and unique within, some "name space". The
821 concept of name and name space should be broadly construed, and not
822 limited to textual names. For example, some name spaces are the
823 domain name system, URLs, ISO Object IDs (OIDs), X.500 Distinguished
824 Names (DNs), and reserved words in a programming language. The
825 mechanisms or conventions used for allocating names and ensuring
826 their uniqueness within their name spaces are beyond the scope of
827 this specification.
828
829 The requirements for these types of UUIDs are as follows:
830
831 o The UUIDs generated at different times from the same name in the
832 same namespace MUST be equal.
833
834 o The UUIDs generated from two different names in the same namespace
835 should be different (with very high probability).
836
837 o The UUIDs generated from the same name in two different namespaces
838 should be different with (very high probability).
839
840 o If two UUIDs that were generated from names are equal, then they
841 were generated from the same name in the same namespace (with very
842 high probability).
843
844 The algorithm for generating a UUID from a name and a name space are
845 as follows:
846
847 o Allocate a UUID to use as a "name space ID" for all UUIDs
848 generated from names in that name space; see <a href="#appendix-C">Appendix C</a> for some
849 pre-defined values.
850
851 o Choose either MD5 [<a href="#ref-4" title='"The MD5 Message-Digest Algorithm "'>4</a>] or SHA-1 [<a href="#ref-8" title='"Secure Hash Standard"'>8</a>] as the hash algorithm; If
852 backward compatibility is not an issue, SHA-1 is preferred.
853
854
855
856
857<span class="grey">Leach, et al. Standards Track [Page 13]</span>
858</pre><pre class='newpage'><a name="page-14" id="page-14" href="#page-14" class="invisible"> </a>
859<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
860
861
862 o Convert the name to a canonical sequence of octets (as defined by
863 the standards or conventions of its name space); put the name
864 space ID in network byte order.
865
866 o Compute the hash of the name space ID concatenated with the name.
867
868 o Set octets zero through 3 of the time_low field to octets zero
869 through 3 of the hash.
870
871 o Set octets zero and one of the time_mid field to octets 4 and 5 of
872 the hash.
873
874 o Set octets zero and one of the time_hi_and_version field to octets
875 6 and 7 of the hash.
876
877 o Set the four most significant bits (bits 12 through 15) of the
878 time_hi_and_version field to the appropriate 4-bit version number
879 from <a href="#section-4.1.3">Section 4.1.3</a>.
880
881 o Set the clock_seq_hi_and_reserved field to octet 8 of the hash.
882
883 o Set the two most significant bits (bits 6 and 7) of the
884 clock_seq_hi_and_reserved to zero and one, respectively.
885
886 o Set the clock_seq_low field to octet 9 of the hash.
887
888 o Set octets zero through five of the node field to octets 10
889 through 15 of the hash.
890
891 o Convert the resulting UUID to local byte order.
892
893<span class="h3"><a name="section-4.4">4.4</a>. Algorithms for Creating a UUID from Truly Random or</span>
894 Pseudo-Random Numbers
895
896 The version 4 UUID is meant for generating UUIDs from truly-random or
897 pseudo-random numbers.
898
899 The algorithm is as follows:
900
901 o Set the two most significant bits (bits 6 and 7) of the
902 clock_seq_hi_and_reserved to zero and one, respectively.
903
904 o Set the four most significant bits (bits 12 through 15) of the
905 time_hi_and_version field to the 4-bit version number from
906 <a href="#section-4.1.3">Section 4.1.3</a>.
907
908 o Set all the other bits to randomly (or pseudo-randomly) chosen
909 values.
910
911
912
913<span class="grey">Leach, et al. Standards Track [Page 14]</span>
914</pre><pre class='newpage'><a name="page-15" id="page-15" href="#page-15" class="invisible"> </a>
915<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
916
917
918 See <a href="#section-4.5">Section 4.5</a> for a discussion on random numbers.
919
920<span class="h3"><a name="section-4.5">4.5</a>. Node IDs that Do Not Identify the Host</span>
921
922 This section describes how to generate a version 1 UUID if an IEEE
923 802 address is not available, or its use is not desired.
924
925 One approach is to contact the IEEE and get a separate block of
926 addresses. At the time of writing, the application could be found at
927 &lt;<a href="http://standards.ieee.org/regauth/oui/pilot-ind.html">http://standards.ieee.org/regauth/oui/pilot-ind.html</a>&gt;, and the cost
928 was US$550.
929
930 A better solution is to obtain a 47-bit cryptographic quality random
931 number and use it as the low 47 bits of the node ID, with the least
932 significant bit of the first octet of the node ID set to one. This
933 bit is the unicast/multicast bit, which will never be set in IEEE 802
934 addresses obtained from network cards. Hence, there can never be a
935 conflict between UUIDs generated by machines with and without network
936 cards. (Recall that the IEEE 802 spec talks about transmission
937 order, which is the opposite of the in-memory representation that is
938 discussed in this document.)
939
940 For compatibility with earlier specifications, note that this
941 document uses the unicast/multicast bit, instead of the arguably more
942 correct local/global bit.
943
944 Advice on generating cryptographic-quality random numbers can be
945 found in <a href="./rfc1750">RFC1750</a> [<a href="#ref-5" title='"Randomness Requirements for Security"'>5</a>].
946
947 In addition, items such as the computer's name and the name of the
948 operating system, while not strictly speaking random, will help
949 differentiate the results from those obtained by other systems.
950
951 The exact algorithm to generate a node ID using these data is system
952 specific, because both the data available and the functions to obtain
953 them are often very system specific. A generic approach, however, is
954 to accumulate as many sources as possible into a buffer, use a
955 message digest such as MD5 [<a href="#ref-4" title='"The MD5 Message-Digest Algorithm "'>4</a>] or SHA-1 [<a href="#ref-8" title='"Secure Hash Standard"'>8</a>], take an arbitrary 6
956 bytes from the hash value, and set the multicast bit as described
957 above.
958
959<span class="h2"><a name="section-5">5</a>. Community Considerations</span>
960
961 The use of UUIDs is extremely pervasive in computing. They comprise
962 the core identifier infrastructure for many operating systems
963 (Microsoft Windows) and applications (the Mozilla browser) and in
964 many cases, become exposed to the Web in many non-standard ways.
965
966
967
968
969<span class="grey">Leach, et al. Standards Track [Page 15]</span>
970</pre><pre class='newpage'><a name="page-16" id="page-16" href="#page-16" class="invisible"> </a>
971<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
972
973
974 This specification attempts to standardize that practice as openly as
975 possible and in a way that attempts to benefit the entire Internet.
976
977<span class="h2"><a name="section-6">6</a>. Security Considerations</span>
978
979 Do not assume that UUIDs are hard to guess; they should not be used
980 as security capabilities (identifiers whose mere possession grants
981 access), for example. A predictable random number source will
982 exacerbate the situation.
983
984 Do not assume that it is easy to determine if a UUID has been
985 slightly transposed in order to redirect a reference to another
986 object. Humans do not have the ability to easily check the integrity
987 of a UUID by simply glancing at it.
988
989 Distributed applications generating UUIDs at a variety of hosts must
990 be willing to rely on the random number source at all hosts. If this
991 is not feasible, the namespace variant should be used.
992
993<span class="h2"><a name="section-7">7</a>. Acknowledgments</span>
994
995 This document draws heavily on the OSF DCE specification for UUIDs.
996 Ted Ts'o provided helpful comments, especially on the byte ordering
997 section which we mostly plagiarized from a proposed wording he
998 supplied (all errors in that section are our responsibility,
999 however).
1000
1001 We are also grateful to the careful reading and bit-twiddling of Ralf
1002 S. Engelschall, John Larmouth, and Paul Thorpe. Professor Larmouth
1003 was also invaluable in achieving coordination with ISO/IEC.
1004
1005<span class="h2"><a name="section-8">8</a>. Normative References</span>
1006
1007 [<a name="ref-1" id="ref-1">1</a>] Zahn, L., Dineen, T., and P. Leach, "Network Computing
1008 Architecture", ISBN 0-13-611674-4, January 1990.
1009
1010 [<a name="ref-2" id="ref-2">2</a>] "DCE: Remote Procedure Call", Open Group CAE Specification C309,
1011 ISBN 1-85912-041-5, August 1994.
1012
1013 [<a name="ref-3" id="ref-3">3</a>] ISO/IEC 9834-8:2004 Information Technology, "Procedures for the
1014 operation of OSI Registration Authorities: Generation and
1015 registration of Universally Unique Identifiers (UUIDs) and their
1016 use as ASN.1 Object Identifier components" ITU-T Rec. X.667,
1017 2004.
1018
1019 [<a name="ref-4" id="ref-4">4</a>] Rivest, R., "The MD5 Message-Digest Algorithm ", <a href="./rfc1321">RFC 1321</a>, April
1020 1992.
1021
1022
1023
1024
1025<span class="grey">Leach, et al. Standards Track [Page 16]</span>
1026</pre><pre class='newpage'><a name="page-17" id="page-17" href="#page-17" class="invisible"> </a>
1027<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1028
1029
1030 [<a name="ref-5" id="ref-5">5</a>] Eastlake, D., 3rd, Schiller, J., and S. Crocker, "Randomness
1031 Requirements for Security", <a href="./bcp106">BCP 106</a>, <a href="./rfc4086">RFC 4086</a>, June 2005.
1032
1033 [<a name="ref-6" id="ref-6">6</a>] Moats, R., "URN Syntax", <a href="./rfc2141">RFC 2141</a>, May 1997.
1034
1035 [<a name="ref-7" id="ref-7">7</a>] Crocker, D. and P. Overell, "Augmented BNF for Syntax
1036 Specifications: ABNF", <a href="./rfc2234">RFC 2234</a>, November 1997.
1037
1038 [<a name="ref-8" id="ref-8">8</a>] National Institute of Standards and Technology, "Secure Hash
1039 Standard", FIPS PUB 180-1, April 1995,
1040 &lt;<a href="http://www.itl.nist.gov/fipspubs/fip180-1.htm">http://www.itl.nist.gov/fipspubs/fip180-1.htm</a>&gt;.
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081<span class="grey">Leach, et al. Standards Track [Page 17]</span>
1082</pre><pre class='newpage'><a name="page-18" id="page-18" href="#page-18" class="invisible"> </a>
1083<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1084
1085
1086<span class="h2"><a name="appendix-A">Appendix A</a>. <a href="#appendix-A">Appendix A</a> - Sample Implementation</span>
1087
1088 This implementation consists of 5 files: uuid.h, uuid.c, sysdep.h,
1089 sysdep.c and utest.c. The uuid.* files are the system independent
1090 implementation of the UUID generation algorithms described above,
1091 with all the optimizations described above except efficient state
1092 sharing across processes included. The code has been tested on Linux
1093 (Red Hat 4.0) with GCC (2.7.2), and Windows NT 4.0 with VC++ 5.0.
1094 The code assumes 64-bit integer support, which makes it much clearer.
1095
1096 All the following source files should have the following copyright
1097 notice included:
1098
1099copyrt.h
1100
1101/*
1102** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
1103** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &amp;
1104** Digital Equipment Corporation, Maynard, Mass.
1105** Copyright (c) 1998 Microsoft.
1106** To anyone who acknowledges that this file is provided "AS IS"
1107** without any express or implied warranty: permission to use, copy,
1108** modify, and distribute this file for any purpose is hereby
1109** granted without fee, provided that the above copyright notices and
1110** this notice appears in all source code copies, and that none of
1111** the names of Open Software Foundation, Inc., Hewlett-Packard
1112** Company, Microsoft, or Digital Equipment Corporation be used in
1113** advertising or publicity pertaining to distribution of the software
1114** without specific, written prior permission. Neither Open Software
1115** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital
1116** Equipment Corporation makes any representations about the
1117** suitability of this software for any purpose.
1118*/
1119
1120
1121uuid.h
1122
1123#include "copyrt.h"
1124#undef uuid_t
1125typedef struct {
1126 unsigned32 time_low;
1127 unsigned16 time_mid;
1128 unsigned16 time_hi_and_version;
1129 unsigned8 clock_seq_hi_and_reserved;
1130 unsigned8 clock_seq_low;
1131 byte node[6];
1132} uuid_t;
1133
1134
1135
1136
1137<span class="grey">Leach, et al. Standards Track [Page 18]</span>
1138</pre><pre class='newpage'><a name="page-19" id="page-19" href="#page-19" class="invisible"> </a>
1139<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1140
1141
1142/* uuid_create -- generate a UUID */
1143int uuid_create(uuid_t * uuid);
1144
1145/* uuid_create_md5_from_name -- create a version 3 (MD5) UUID using a
1146 "name" from a "name space" */
1147void uuid_create_md5_from_name(
1148 uuid_t *uuid, /* resulting UUID */
1149 uuid_t nsid, /* UUID of the namespace */
1150 void *name, /* the name from which to generate a UUID */
1151 int namelen /* the length of the name */
1152);
1153
1154/* uuid_create_sha1_from_name -- create a version 5 (SHA-1) UUID
1155 using a "name" from a "name space" */
1156void uuid_create_sha1_from_name(
1157
1158 uuid_t *uuid, /* resulting UUID */
1159 uuid_t nsid, /* UUID of the namespace */
1160 void *name, /* the name from which to generate a UUID */
1161 int namelen /* the length of the name */
1162);
1163
1164/* uuid_compare -- Compare two UUID's "lexically" and return
1165 -1 u1 is lexically before u2
1166 0 u1 is equal to u2
1167 1 u1 is lexically after u2
1168 Note that lexical ordering is not temporal ordering!
1169*/
1170int uuid_compare(uuid_t *u1, uuid_t *u2);
1171
1172
1173uuid.c
1174
1175#include "copyrt.h"
1176#include &lt;string.h&gt;
1177#include &lt;stdio.h&gt;
1178#include &lt;stdlib.h&gt;
1179#include &lt;time.h&gt;
1180#include "sysdep.h"
1181#include "uuid.h"
1182
1183/* various forward declarations */
1184static int read_state(unsigned16 *clockseq, uuid_time_t *timestamp,
1185 uuid_node_t *node);
1186static void write_state(unsigned16 clockseq, uuid_time_t timestamp,
1187 uuid_node_t node);
1188static void format_uuid_v1(uuid_t *uuid, unsigned16 clockseq,
1189 uuid_time_t timestamp, uuid_node_t node);
1190
1191
1192
1193<span class="grey">Leach, et al. Standards Track [Page 19]</span>
1194</pre><pre class='newpage'><a name="page-20" id="page-20" href="#page-20" class="invisible"> </a>
1195<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1196
1197
1198static void format_uuid_v3or5(uuid_t *uuid, unsigned char hash[16],
1199 int v);
1200static void get_current_time(uuid_time_t *timestamp);
1201static unsigned16 true_random(void);
1202
1203/* uuid_create -- generator a UUID */
1204int uuid_create(uuid_t *uuid)
1205{
1206 uuid_time_t timestamp, last_time;
1207 unsigned16 clockseq;
1208 uuid_node_t node;
1209 uuid_node_t last_node;
1210 int f;
1211
1212 /* acquire system-wide lock so we're alone */
1213 LOCK;
1214 /* get time, node ID, saved state from non-volatile storage */
1215 get_current_time(&amp;timestamp);
1216 get_ieee_node_identifier(&amp;node);
1217 f = read_state(&amp;clockseq, &amp;last_time, &amp;last_node);
1218
1219 /* if no NV state, or if clock went backwards, or node ID
1220 changed (e.g., new network card) change clockseq */
1221 if (!f || memcmp(&amp;node, &amp;last_node, sizeof node))
1222 clockseq = true_random();
1223 else if (timestamp &lt; last_time)
1224 clockseq++;
1225
1226 /* save the state for next time */
1227 write_state(clockseq, timestamp, node);
1228
1229 UNLOCK;
1230
1231 /* stuff fields into the UUID */
1232 format_uuid_v1(uuid, clockseq, timestamp, node);
1233 return 1;
1234}
1235
1236/* format_uuid_v1 -- make a UUID from the timestamp, clockseq,
1237 and node ID */
1238void format_uuid_v1(uuid_t* uuid, unsigned16 clock_seq,
1239 uuid_time_t timestamp, uuid_node_t node)
1240{
1241 /* Construct a version 1 uuid with the information we've gathered
1242 plus a few constants. */
1243 uuid-&gt;time_low = (unsigned long)(timestamp &amp; 0xFFFFFFFF);
1244 uuid-&gt;time_mid = (unsigned short)((timestamp &gt;&gt; 32) &amp; 0xFFFF);
1245 uuid-&gt;time_hi_and_version =
1246
1247
1248
1249<span class="grey">Leach, et al. Standards Track [Page 20]</span>
1250</pre><pre class='newpage'><a name="page-21" id="page-21" href="#page-21" class="invisible"> </a>
1251<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1252
1253
1254 (unsigned short)((timestamp &gt;&gt; 48) &amp; 0x0FFF);
1255 uuid-&gt;time_hi_and_version |= (1 &lt;&lt; 12);
1256 uuid-&gt;clock_seq_low = clock_seq &amp; 0xFF;
1257 uuid-&gt;clock_seq_hi_and_reserved = (clock_seq &amp; 0x3F00) &gt;&gt; 8;
1258 uuid-&gt;clock_seq_hi_and_reserved |= 0x80;
1259 memcpy(&amp;uuid-&gt;node, &amp;node, sizeof uuid-&gt;node);
1260}
1261
1262/* data type for UUID generator persistent state */
1263typedef struct {
1264 uuid_time_t ts; /* saved timestamp */
1265 uuid_node_t node; /* saved node ID */
1266 unsigned16 cs; /* saved clock sequence */
1267} uuid_state;
1268
1269static uuid_state st;
1270
1271/* read_state -- read UUID generator state from non-volatile store */
1272int read_state(unsigned16 *clockseq, uuid_time_t *timestamp,
1273 uuid_node_t *node)
1274{
1275 static int inited = 0;
1276 FILE *fp;
1277
1278 /* only need to read state once per boot */
1279 if (!inited) {
1280 fp = fopen("state", "rb");
1281 if (fp == NULL)
1282 return 0;
1283 fread(&amp;st, sizeof st, 1, fp);
1284 fclose(fp);
1285 inited = 1;
1286 }
1287 *clockseq = st.cs;
1288 *timestamp = st.ts;
1289 *node = st.node;
1290 return 1;
1291}
1292
1293/* write_state -- save UUID generator state back to non-volatile
1294 storage */
1295void write_state(unsigned16 clockseq, uuid_time_t timestamp,
1296 uuid_node_t node)
1297{
1298 static int inited = 0;
1299 static uuid_time_t next_save;
1300 FILE* fp;
1301
1302
1303
1304
1305<span class="grey">Leach, et al. Standards Track [Page 21]</span>
1306</pre><pre class='newpage'><a name="page-22" id="page-22" href="#page-22" class="invisible"> </a>
1307<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1308
1309
1310 if (!inited) {
1311 next_save = timestamp;
1312 inited = 1;
1313 }
1314
1315 /* always save state to volatile shared state */
1316 st.cs = clockseq;
1317 st.ts = timestamp;
1318 st.node = node;
1319 if (timestamp &gt;= next_save) {
1320 fp = fopen("state", "wb");
1321 fwrite(&amp;st, sizeof st, 1, fp);
1322 fclose(fp);
1323 /* schedule next save for 10 seconds from now */
1324 next_save = timestamp + (10 * 10 * 1000 * 1000);
1325 }
1326}
1327
1328/* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch.
1329 Compensate for the fact that real clock resolution is
1330 less than 100ns. */
1331void get_current_time(uuid_time_t *timestamp)
1332{
1333 static int inited = 0;
1334 static uuid_time_t time_last;
1335 static unsigned16 uuids_this_tick;
1336 uuid_time_t time_now;
1337
1338 if (!inited) {
1339 get_system_time(&amp;time_now);
1340 uuids_this_tick = UUIDS_PER_TICK;
1341 inited = 1;
1342 }
1343
1344 for ( ; ; ) {
1345 get_system_time(&amp;time_now);
1346
1347 /* if clock reading changed since last UUID generated, */
1348 if (time_last != time_now) {
1349 /* reset count of uuids gen'd with this clock reading */
1350 uuids_this_tick = 0;
1351 time_last = time_now;
1352 break;
1353 }
1354 if (uuids_this_tick &lt; UUIDS_PER_TICK) {
1355 uuids_this_tick++;
1356 break;
1357 }
1358
1359
1360
1361<span class="grey">Leach, et al. Standards Track [Page 22]</span>
1362</pre><pre class='newpage'><a name="page-23" id="page-23" href="#page-23" class="invisible"> </a>
1363<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1364
1365
1366 /* going too fast for our clock; spin */
1367 }
1368 /* add the count of uuids to low order bits of the clock reading */
1369 *timestamp = time_now + uuids_this_tick;
1370}
1371
1372/* true_random -- generate a crypto-quality random number.
1373 **This sample doesn't do that.** */
1374static unsigned16 true_random(void)
1375{
1376 static int inited = 0;
1377 uuid_time_t time_now;
1378
1379 if (!inited) {
1380 get_system_time(&amp;time_now);
1381 time_now = time_now / UUIDS_PER_TICK;
1382 srand((unsigned int)
1383 (((time_now &gt;&gt; 32) ^ time_now) &amp; 0xffffffff));
1384 inited = 1;
1385 }
1386
1387 return rand();
1388}
1389
1390/* uuid_create_md5_from_name -- create a version 3 (MD5) UUID using a
1391 "name" from a "name space" */
1392void uuid_create_md5_from_name(uuid_t *uuid, uuid_t nsid, void *name,
1393 int namelen)
1394{
1395 MD5_CTX c;
1396 unsigned char hash[16];
1397 uuid_t net_nsid;
1398
1399 /* put name space ID in network byte order so it hashes the same
1400 no matter what endian machine we're on */
1401 net_nsid = nsid;
1402 net_nsid.time_low = htonl(net_nsid.time_low);
1403 net_nsid.time_mid = htons(net_nsid.time_mid);
1404 net_nsid.time_hi_and_version = htons(net_nsid.time_hi_and_version);
1405
1406 MD5Init(&amp;c);
1407 MD5Update(&amp;c, &amp;net_nsid, sizeof net_nsid);
1408 MD5Update(&amp;c, name, namelen);
1409 MD5Final(hash, &amp;c);
1410
1411 /* the hash is in network byte order at this point */
1412 format_uuid_v3or5(uuid, hash, 3);
1413}
1414
1415
1416
1417<span class="grey">Leach, et al. Standards Track [Page 23]</span>
1418</pre><pre class='newpage'><a name="page-24" id="page-24" href="#page-24" class="invisible"> </a>
1419<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1420
1421
1422void uuid_create_sha1_from_name(uuid_t *uuid, uuid_t nsid, void *name,
1423 int namelen)
1424{
1425 SHA_CTX c;
1426 unsigned char hash[20];
1427 uuid_t net_nsid;
1428
1429 /* put name space ID in network byte order so it hashes the same
1430 no matter what endian machine we're on */
1431 net_nsid = nsid;
1432 net_nsid.time_low = htonl(net_nsid.time_low);
1433 net_nsid.time_mid = htons(net_nsid.time_mid);
1434 net_nsid.time_hi_and_version = htons(net_nsid.time_hi_and_version);
1435
1436 SHA1_Init(&amp;c);
1437 SHA1_Update(&amp;c, &amp;net_nsid, sizeof net_nsid);
1438 SHA1_Update(&amp;c, name, namelen);
1439 SHA1_Final(hash, &amp;c);
1440
1441 /* the hash is in network byte order at this point */
1442 format_uuid_v3or5(uuid, hash, 5);
1443}
1444
1445/* format_uuid_v3or5 -- make a UUID from a (pseudo)random 128-bit
1446 number */
1447void format_uuid_v3or5(uuid_t *uuid, unsigned char hash[16], int v)
1448{
1449 /* convert UUID to local byte order */
1450 memcpy(uuid, hash, sizeof *uuid);
1451 uuid-&gt;time_low = ntohl(uuid-&gt;time_low);
1452 uuid-&gt;time_mid = ntohs(uuid-&gt;time_mid);
1453 uuid-&gt;time_hi_and_version = ntohs(uuid-&gt;time_hi_and_version);
1454
1455 /* put in the variant and version bits */
1456 uuid-&gt;time_hi_and_version &amp;= 0x0FFF;
1457 uuid-&gt;time_hi_and_version |= (v &lt;&lt; 12);
1458 uuid-&gt;clock_seq_hi_and_reserved &amp;= 0x3F;
1459 uuid-&gt;clock_seq_hi_and_reserved |= 0x80;
1460}
1461
1462/* uuid_compare -- Compare two UUID's "lexically" and return */
1463#define CHECK(f1, f2) if (f1 != f2) return f1 &lt; f2 ? -1 : 1;
1464int uuid_compare(uuid_t *u1, uuid_t *u2)
1465{
1466 int i;
1467
1468 CHECK(u1-&gt;time_low, u2-&gt;time_low);
1469 CHECK(u1-&gt;time_mid, u2-&gt;time_mid);
1470
1471
1472
1473<span class="grey">Leach, et al. Standards Track [Page 24]</span>
1474</pre><pre class='newpage'><a name="page-25" id="page-25" href="#page-25" class="invisible"> </a>
1475<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1476
1477
1478 CHECK(u1-&gt;time_hi_and_version, u2-&gt;time_hi_and_version);
1479 CHECK(u1-&gt;clock_seq_hi_and_reserved, u2-&gt;clock_seq_hi_and_reserved);
1480 CHECK(u1-&gt;clock_seq_low, u2-&gt;clock_seq_low)
1481 for (i = 0; i &lt; 6; i++) {
1482 if (u1-&gt;node[i] &lt; u2-&gt;node[i])
1483 return -1;
1484 if (u1-&gt;node[i] &gt; u2-&gt;node[i])
1485 return 1;
1486 }
1487 return 0;
1488}
1489#undef CHECK
1490
1491
1492sysdep.h
1493
1494#include "copyrt.h"
1495/* remove the following define if you aren't running WIN32 */
1496#define WININC 0
1497
1498#ifdef WININC
1499#include &lt;windows.h&gt;
1500#else
1501#include &lt;sys/types.h&gt;
1502#include &lt;sys/time.h&gt;
1503#include &lt;sys/sysinfo.h&gt;
1504#endif
1505
1506#include "global.h"
1507/* change to point to where MD5 .h's live; <a href="./rfc1321">RFC 1321</a> has sample
1508 implementation */
1509#include "md5.h"
1510
1511/* set the following to the number of 100ns ticks of the actual
1512 resolution of your system's clock */
1513#define UUIDS_PER_TICK 1024
1514
1515/* Set the following to a calls to get and release a global lock */
1516#define LOCK
1517#define UNLOCK
1518
1519typedef unsigned long unsigned32;
1520typedef unsigned short unsigned16;
1521typedef unsigned char unsigned8;
1522typedef unsigned char byte;
1523
1524/* Set this to what your compiler uses for 64-bit data type */
1525#ifdef WININC
1526
1527
1528
1529<span class="grey">Leach, et al. Standards Track [Page 25]</span>
1530</pre><pre class='newpage'><a name="page-26" id="page-26" href="#page-26" class="invisible"> </a>
1531<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1532
1533
1534#define unsigned64_t unsigned __int64
1535#define I64(C) C
1536#else
1537#define unsigned64_t unsigned long long
1538#define I64(C) C##LL
1539#endif
1540
1541typedef unsigned64_t uuid_time_t;
1542typedef struct {
1543 char nodeID[6];
1544} uuid_node_t;
1545
1546void get_ieee_node_identifier(uuid_node_t *node);
1547void get_system_time(uuid_time_t *uuid_time);
1548void get_random_info(char seed[16]);
1549
1550
1551sysdep.c
1552
1553#include "copyrt.h"
1554#include &lt;stdio.h&gt;
1555#include "sysdep.h"
1556
1557/* system dependent call to get IEEE node ID.
1558 This sample implementation generates a random node ID. */
1559void get_ieee_node_identifier(uuid_node_t *node)
1560{
1561 static inited = 0;
1562 static uuid_node_t saved_node;
1563 char seed[16];
1564 FILE *fp;
1565
1566 if (!inited) {
1567 fp = fopen("nodeid", "rb");
1568 if (fp) {
1569 fread(&amp;saved_node, sizeof saved_node, 1, fp);
1570 fclose(fp);
1571 }
1572 else {
1573 get_random_info(seed);
1574 seed[0] |= 0x01;
1575 memcpy(&amp;saved_node, seed, sizeof saved_node);
1576 fp = fopen("nodeid", "wb");
1577 if (fp) {
1578 fwrite(&amp;saved_node, sizeof saved_node, 1, fp);
1579 fclose(fp);
1580 }
1581 }
1582
1583
1584
1585<span class="grey">Leach, et al. Standards Track [Page 26]</span>
1586</pre><pre class='newpage'><a name="page-27" id="page-27" href="#page-27" class="invisible"> </a>
1587<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1588
1589
1590 inited = 1;
1591 }
1592
1593 *node = saved_node;
1594}
1595
1596/* system dependent call to get the current system time. Returned as
1597 100ns ticks since UUID epoch, but resolution may be less than
1598 100ns. */
1599#ifdef _WINDOWS_
1600
1601void get_system_time(uuid_time_t *uuid_time)
1602{
1603 ULARGE_INTEGER time;
1604
1605 /* NT keeps time in FILETIME format which is 100ns ticks since
1606 Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582.
1607 The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec)
1608 + 18 years and 5 leap days. */
1609 GetSystemTimeAsFileTime((FILETIME *)&amp;time);
1610 time.QuadPart +=
1611
1612 (unsigned __int64) (1000*1000*10) // seconds
1613 * (unsigned __int64) (60 * 60 * 24) // days
1614 * (unsigned __int64) (17+30+31+365*18+5); // # of days
1615 *uuid_time = time.QuadPart;
1616}
1617
1618/* Sample code, not for use in production; see <a href="./rfc1750">RFC 1750</a> */
1619void get_random_info(char seed[16])
1620{
1621 MD5_CTX c;
1622 struct {
1623 MEMORYSTATUS m;
1624 SYSTEM_INFO s;
1625 FILETIME t;
1626 LARGE_INTEGER pc;
1627 DWORD tc;
1628 DWORD l;
1629 char hostname[MAX_COMPUTERNAME_LENGTH + 1];
1630 } r;
1631
1632 MD5Init(&amp;c);
1633 GlobalMemoryStatus(&amp;r.m);
1634 GetSystemInfo(&amp;r.s);
1635 GetSystemTimeAsFileTime(&amp;r.t);
1636 QueryPerformanceCounter(&amp;r.pc);
1637 r.tc = GetTickCount();
1638
1639
1640
1641<span class="grey">Leach, et al. Standards Track [Page 27]</span>
1642</pre><pre class='newpage'><a name="page-28" id="page-28" href="#page-28" class="invisible"> </a>
1643<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1644
1645
1646 r.l = MAX_COMPUTERNAME_LENGTH + 1;
1647 GetComputerName(r.hostname, &amp;r.l);
1648 MD5Update(&amp;c, &amp;r, sizeof r);
1649 MD5Final(seed, &amp;c);
1650}
1651
1652#else
1653
1654void get_system_time(uuid_time_t *uuid_time)
1655{
1656 struct timeval tp;
1657
1658 gettimeofday(&amp;tp, (struct timezone *)0);
1659
1660 /* Offset between UUID formatted times and Unix formatted times.
1661 UUID UTC base time is October 15, 1582.
1662 Unix base time is January 1, 1970.*/
1663 *uuid_time = ((unsigned64)tp.tv_sec * 10000000)
1664 + ((unsigned64)tp.tv_usec * 10)
1665 + I64(0x01B21DD213814000);
1666}
1667
1668/* Sample code, not for use in production; see <a href="./rfc1750">RFC 1750</a> */
1669void get_random_info(char seed[16])
1670{
1671 MD5_CTX c;
1672 struct {
1673 struct sysinfo s;
1674 struct timeval t;
1675 char hostname[257];
1676 } r;
1677
1678 MD5Init(&amp;c);
1679 sysinfo(&amp;r.s);
1680 gettimeofday(&amp;r.t, (struct timezone *)0);
1681 gethostname(r.hostname, 256);
1682 MD5Update(&amp;c, &amp;r, sizeof r);
1683 MD5Final(seed, &amp;c);
1684}
1685
1686#endif
1687
1688utest.c
1689
1690#include "copyrt.h"
1691#include "sysdep.h"
1692#include &lt;stdio.h&gt;
1693#include "uuid.h"
1694
1695
1696
1697<span class="grey">Leach, et al. Standards Track [Page 28]</span>
1698</pre><pre class='newpage'><a name="page-29" id="page-29" href="#page-29" class="invisible"> </a>
1699<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1700
1701
1702uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */
1703 0x6ba7b810,
1704 0x9dad,
1705 0x11d1,
1706 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
1707};
1708
1709/* puid -- print a UUID */
1710void puid(uuid_t u)
1711{
1712 int i;
1713
1714 printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid,
1715 u.time_hi_and_version, u.clock_seq_hi_and_reserved,
1716 u.clock_seq_low);
1717 for (i = 0; i &lt; 6; i++)
1718 printf("%2.2x", u.node[i]);
1719 printf("\n");
1720}
1721
1722/* Simple driver for UUID generator */
1723void main(int argc, char **argv)
1724{
1725 uuid_t u;
1726 int f;
1727
1728 uuid_create(&amp;u);
1729 printf("uuid_create(): "); puid(u);
1730
1731 f = uuid_compare(&amp;u, &amp;u);
1732 printf("uuid_compare(u,u): %d\n", f); /* should be 0 */
1733 f = uuid_compare(&amp;u, &amp;NameSpace_DNS);
1734 printf("uuid_compare(u, NameSpace_DNS): %d\n", f); /* s.b. 1 */
1735 f = uuid_compare(&amp;NameSpace_DNS, &amp;u);
1736 printf("uuid_compare(NameSpace_DNS, u): %d\n", f); /* s.b. -1 */
1737 uuid_create_md5_from_name(&amp;u, NameSpace_DNS, "www.widgets.com", 15);
1738 printf("uuid_create_md5_from_name(): "); puid(u);
1739}
1740
1741<span class="h2"><a name="appendix-B">Appendix B</a>. <a href="#appendix-B">Appendix B</a> - Sample Output of utest</span>
1742
1743 uuid_create(): 7d444840-9dc0-11d1-b245-5ffdce74fad2
1744 uuid_compare(u,u): 0
1745 uuid_compare(u, NameSpace_DNS): 1
1746 uuid_compare(NameSpace_DNS, u): -1
1747 uuid_create_md5_from_name(): e902893a-9d22-3c7e-a7b8-d6e313b71d9f
1748
1749
1750
1751
1752
1753<span class="grey">Leach, et al. Standards Track [Page 29]</span>
1754</pre><pre class='newpage'><a name="page-30" id="page-30" href="#page-30" class="invisible"> </a>
1755<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1756
1757
1758<span class="h2"><a name="appendix-C">Appendix C</a>. <a href="#appendix-C">Appendix C</a> - Some Name Space IDs</span>
1759
1760 This appendix lists the name space IDs for some potentially
1761 interesting name spaces, as initialized C structures and in the
1762 string representation defined above.
1763
1764 /* Name string is a fully-qualified domain name */
1765 uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */
1766 0x6ba7b810,
1767 0x9dad,
1768 0x11d1,
1769 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
1770 };
1771
1772 /* Name string is a URL */
1773 uuid_t NameSpace_URL = { /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */
1774 0x6ba7b811,
1775 0x9dad,
1776 0x11d1,
1777 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
1778 };
1779
1780 /* Name string is an ISO OID */
1781 uuid_t NameSpace_OID = { /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */
1782 0x6ba7b812,
1783 0x9dad,
1784 0x11d1,
1785 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
1786 };
1787
1788 /* Name string is an X.500 DN (in DER or a text output format) */
1789 uuid_t NameSpace_X500 = { /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */
1790 0x6ba7b814,
1791 0x9dad,
1792 0x11d1,
1793 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
1794 };
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809<span class="grey">Leach, et al. Standards Track [Page 30]</span>
1810</pre><pre class='newpage'><a name="page-31" id="page-31" href="#page-31" class="invisible"> </a>
1811<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1812
1813
1814Authors' Addresses
1815
1816 Paul J. Leach
1817 Microsoft
1818 1 Microsoft Way
1819 Redmond, WA 98052
1820 US
1821
1822 Phone: +1 425-882-8080
1823 EMail: paulle@microsoft.com
1824
1825
1826 Michael Mealling
1827 Refactored Networks, LLC
1828 1635 Old Hwy 41
1829 Suite 112, Box 138
1830 Kennesaw, GA 30152
1831 US
1832
1833 Phone: +1-678-581-9656
1834 EMail: michael@refactored-networks.com
1835 URI: <a href="http://www.refactored-networks.com">http://www.refactored-networks.com</a>
1836
1837
1838 Rich Salz
1839 DataPower Technology, Inc.
1840 1 Alewife Center
1841 Cambridge, MA 02142
1842 US
1843
1844 Phone: +1 617-864-0455
1845 EMail: rsalz@datapower.com
1846 URI: <a href="http://www.datapower.com">http://www.datapower.com</a>
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865<span class="grey">Leach, et al. Standards Track [Page 31]</span>
1866</pre><pre class='newpage'><a name="page-32" id="page-32" href="#page-32" class="invisible"> </a>
1867<span class="grey"><a href="./rfc4122">RFC 4122</a> A UUID URN Namespace July 2005</span>
1868
1869
1870Full Copyright Statement
1871
1872 Copyright (C) The Internet Society (2005).
1873
1874 This document is subject to the rights, licenses and restrictions
1875 contained in <a href="./bcp78">BCP 78</a>, and except as set forth therein, the authors
1876 retain all their rights.
1877
1878 This document and the information contained herein are provided on an
1879 "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
1880 OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
1881 ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
1882 INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
1883 INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
1884 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
1885
1886Intellectual Property
1887
1888 The IETF takes no position regarding the validity or scope of any
1889 Intellectual Property Rights or other rights that might be claimed to
1890 pertain to the implementation or use of the technology described in
1891 this document or the extent to which any license under such rights
1892 might or might not be available; nor does it represent that it has
1893 made any independent effort to identify any such rights. Information
1894 on the procedures with respect to rights in RFC documents can be
1895 found in <a href="./bcp78">BCP 78</a> and <a href="./bcp79">BCP 79</a>.
1896
1897 Copies of IPR disclosures made to the IETF Secretariat and any
1898 assurances of licenses to be made available, or the result of an
1899 attempt made to obtain a general license or permission for the use of
1900 such proprietary rights by implementers or users of this
1901 specification can be obtained from the IETF on-line IPR repository at
1902 <a href="http://www.ietf.org/ipr">http://www.ietf.org/ipr</a>.
1903
1904 The IETF invites any interested party to bring to its attention any
1905 copyrights, patents or patent applications, or other proprietary
1906 rights that may cover technology that may be required to implement
1907 this standard. Please address the information to the IETF at ietf-
1908 ipr@ietf.org.
1909
1910Acknowledgement
1911
1912 Funding for the RFC Editor function is currently provided by the
1913 Internet Society.
1914
1915
1916
1917
1918
1919
1920
1921Leach, et al. Standards Track [Page 32]
1922</pre><pre class='newpage'>
1923
1924</pre><br />
1925<span class="noprint"><small><small>Html markup produced by rfcmarkup 1.73, available from
1926<a href="http://tools.ietf.org/tools/rfcmarkup/">http://tools.ietf.org/tools/rfcmarkup/</a>
1927</small></small></span>
1928</body></html>
diff --git a/src/formatter.cpp b/src/formatter.cpp
index c6ae3b7..1ec3c39 100644
--- a/src/formatter.cpp
+++ b/src/formatter.cpp
@@ -33,7 +33,7 @@ void Bu::Formatter::writeAligned( const Bu::FString &sStr )
33 { 33 {
34 case Fmt::Right: 34 case Fmt::Right:
35 for( int k = 0; k < iRem; k++ ) 35 for( int k = 0; k < iRem; k++ )
36 write(" ", 1 ); 36 write( &fLast.cFillChar, 1 );
37 write( sStr ); 37 write( sStr );
38 break; 38 break;
39 39
@@ -41,18 +41,18 @@ void Bu::Formatter::writeAligned( const Bu::FString &sStr )
41 { 41 {
42 int iHlf = iRem/2; 42 int iHlf = iRem/2;
43 for( int k = 0; k < iHlf; k++ ) 43 for( int k = 0; k < iHlf; k++ )
44 write(" ", 1 ); 44 write( &fLast.cFillChar, 1 );
45 write( sStr ); 45 write( sStr );
46 iHlf = iRem-iHlf;; 46 iHlf = iRem-iHlf;;
47 for( int k = 0; k < iHlf; k++ ) 47 for( int k = 0; k < iHlf; k++ )
48 write(" ", 1 ); 48 write( &fLast.cFillChar, 1 );
49 } 49 }
50 break; 50 break;
51 51
52 case Fmt::Left: 52 case Fmt::Left:
53 write( sStr ); 53 write( sStr );
54 for( int k = 0; k < iRem; k++ ) 54 for( int k = 0; k < iRem; k++ )
55 write(" ", 1 ); 55 write( &fLast.cFillChar, 1 );
56 break; 56 break;
57 } 57 }
58 } 58 }
@@ -73,7 +73,7 @@ void Bu::Formatter::writeAligned( const char *sStr, int iLen )
73 { 73 {
74 case Fmt::Right: 74 case Fmt::Right:
75 for( int k = 0; k < iRem; k++ ) 75 for( int k = 0; k < iRem; k++ )
76 write(" ", 1 ); 76 write( &fLast.cFillChar, 1 );
77 write( sStr, iLen ); 77 write( sStr, iLen );
78 break; 78 break;
79 79
@@ -81,18 +81,18 @@ void Bu::Formatter::writeAligned( const char *sStr, int iLen )
81 { 81 {
82 int iHlf = iRem/2; 82 int iHlf = iRem/2;
83 for( int k = 0; k < iHlf; k++ ) 83 for( int k = 0; k < iHlf; k++ )
84 write(" ", 1 ); 84 write( &fLast.cFillChar, 1 );
85 write( sStr, iLen ); 85 write( sStr, iLen );
86 iHlf = iRem-iHlf;; 86 iHlf = iRem-iHlf;;
87 for( int k = 0; k < iHlf; k++ ) 87 for( int k = 0; k < iHlf; k++ )
88 write(" ", 1 ); 88 write( &fLast.cFillChar, 1 );
89 } 89 }
90 break; 90 break;
91 91
92 case Fmt::Left: 92 case Fmt::Left:
93 write( sStr, iLen ); 93 write( sStr, iLen );
94 for( int k = 0; k < iRem; k++ ) 94 for( int k = 0; k < iRem; k++ )
95 write(" ", 1 ); 95 write( &fLast.cFillChar, 1 );
96 break; 96 break;
97 } 97 }
98 } 98 }
@@ -100,6 +100,42 @@ void Bu::Formatter::writeAligned( const char *sStr, int iLen )
100 usedFormat(); 100 usedFormat();
101} 101}
102 102
103Bu::Formatter::Fmt &Bu::Formatter::Fmt::width( unsigned int uWidth )
104{
105 this->uMinWidth = uWidth;
106 return *this;
107}
108
109Bu::Formatter::Fmt &Bu::Formatter::Fmt::fill( char cFill )
110{
111 this->cFillChar = (unsigned char)cFill;
112 return *this;
113}
114
115Bu::Formatter::Fmt &Bu::Formatter::Fmt::radix( unsigned int uRadix )
116{
117 this->uRadix = uRadix;
118 return *this;
119}
120
121Bu::Formatter::Fmt &Bu::Formatter::Fmt::align( Alignment eAlign )
122{
123 this->uAlign = eAlign;
124 return *this;
125}
126
127Bu::Formatter::Fmt &Bu::Formatter::Fmt::plus( bool bPlus )
128{
129 this->bPlus = bPlus;
130 return *this;
131}
132
133Bu::Formatter::Fmt &Bu::Formatter::Fmt::caps( bool bCaps )
134{
135 this->bCaps = bCaps;
136 return *this;
137}
138
103Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::Formatter::Fmt &f ) 139Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::Formatter::Fmt &f )
104{ 140{
105 rOut.setTempFormat( f ); 141 rOut.setTempFormat( f );
@@ -195,3 +231,27 @@ Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, unsigned long long i )
195 return rOut; 231 return rOut;
196} 232}
197 233
234Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, float f )
235{
236 rOut.ffmt<float>( f );
237 return rOut;
238}
239
240Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, double f )
241{
242 rOut.ffmt<double>( f );
243 return rOut;
244}
245
246Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, long double f )
247{
248 rOut.ffmt<long double>( f );
249 return rOut;
250}
251
252Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, bool b )
253{
254 rOut.writeAligned( b?("true"):("false") );
255 return rOut;
256}
257
diff --git a/src/formatter.h b/src/formatter.h
index 168f48f..4bab505 100644
--- a/src/formatter.h
+++ b/src/formatter.h
@@ -21,28 +21,65 @@ namespace Bu
21 }; 21 };
22 Fmt() : 22 Fmt() :
23 uMinWidth( 0 ), 23 uMinWidth( 0 ),
24 cFillChar(' '),
24 uRadix( 10 ), 25 uRadix( 10 ),
25 uAlign( Right ), 26 uAlign( Right ),
26 bPlus( false ), 27 bPlus( false ),
27 bCaps( false ) 28 bCaps( true )
28 { 29 {
29 } 30 }
30 31
31 Fmt( unsigned int uMinWidth, unsigned int uRadix=10, 32 Fmt( unsigned int uMinWidth, unsigned int uRadix=10,
32 Alignment a=Right, bool bPlus=false ) : 33 Alignment a=Right, bool bPlus=false, bool bCaps=true,
34 char cFill=' ') :
33 uMinWidth( uMinWidth ), 35 uMinWidth( uMinWidth ),
36 cFillChar(cFill),
34 uRadix( uRadix ), 37 uRadix( uRadix ),
35 uAlign( a ), 38 uAlign( a ),
36 bPlus( bPlus ), 39 bPlus( bPlus ),
37 bCaps( false ) 40 bCaps( bCaps )
38 { 41 {
39 } 42 }
43 Fmt( unsigned int uMinWidth, Alignment a=Right,
44 unsigned int uRadix=10, bool bPlus=false, bool bCaps=true,
45 char cFill=' ') :
46 uMinWidth( uMinWidth ),
47 cFillChar(cFill),
48 uRadix( uRadix ),
49 uAlign( a ),
50 bPlus( bPlus ),
51 bCaps( bCaps )
52 {
53 }
54
55 static Fmt hex( unsigned int uWidth=0, bool bCaps=true )
56 {
57 return Fmt( uWidth, 16, Right, false, bCaps, '0' );
58 }
59
60 static Fmt oct( unsigned int uWidth=0, bool bCaps=true )
61 {
62 return Fmt( uWidth, 8, Right, false, bCaps, '0' );
63 }
40 64
41 unsigned int uMinWidth : 8; 65 static Fmt ptr( bool bCaps=true )
42 unsigned int uRadix : 6; 66 {
43 unsigned int uAlign : 2; 67 return Fmt( sizeof(ptrdiff_t)*2, 16, Right, false, bCaps, '0' );
44 unsigned int bPlus : 1; 68 }
45 unsigned int bCaps : 1; 69
70 Fmt &width( unsigned int uWidth );
71 Fmt &fill( char cFill='0' );
72 Fmt &radix( unsigned int uRadix );
73 Fmt &align( Alignment eAlign );
74 Fmt &plus( bool bPlus=true );
75 Fmt &caps( bool bCaps=true );
76
77 unsigned char uMinWidth;
78 char cFillChar;
79 unsigned short uRadix : 6;
80 unsigned short uAlign : 2;
81 unsigned short bPlus : 1;
82 unsigned short bCaps : 1;
46 } Fmt; 83 } Fmt;
47 84
48 void write( const Bu::FString &sStr ); 85 void write( const Bu::FString &sStr );
@@ -125,6 +162,13 @@ namespace Bu
125 usedFormat(); 162 usedFormat();
126 } 163 }
127 164
165 template<typename type>
166 void ffmt( type /*f*/ )
167 {
168 writeAligned("**make floats work**");
169 usedFormat();
170 }
171
128 enum Special 172 enum Special
129 { 173 {
130 nl 174 nl
@@ -153,6 +197,17 @@ namespace Bu
153 Formatter &operator<<( Formatter &rOut, unsigned long i ); 197 Formatter &operator<<( Formatter &rOut, unsigned long i );
154 Formatter &operator<<( Formatter &rOut, signed long long i ); 198 Formatter &operator<<( Formatter &rOut, signed long long i );
155 Formatter &operator<<( Formatter &rOut, unsigned long long i ); 199 Formatter &operator<<( Formatter &rOut, unsigned long long i );
200 Formatter &operator<<( Formatter &rOut, float f );
201 Formatter &operator<<( Formatter &rOut, double f );
202 Formatter &operator<<( Formatter &rOut, long double f );
203 Formatter &operator<<( Formatter &rOut, bool b );
204
205 template<typename type>
206 Formatter &operator<<( Formatter &rOut, type *p )
207 {
208 rOut << (ptrdiff_t)(p);
209 return rOut;
210 }
156}; 211};
157 212
158#endif 213#endif
diff --git a/src/tests/stdstream.cpp b/src/tests/stdstream.cpp
index d67f9b8..cb22e22 100644
--- a/src/tests/stdstream.cpp
+++ b/src/tests/stdstream.cpp
@@ -1,20 +1,31 @@
1#include "bu/sio.h" 1#include "bu/sio.h"
2 2
3using Bu::sio;
4using Bu::Fmt;
5
3int main() 6int main()
4{ 7{
5 Bu::sio << "Hello there" << Bu::sio.nl; 8 sio << "Hello there" << sio.nl;
9
10 sio << "sizeof(Fmt) = " << sizeof(Fmt) << sio.nl;
11
12 sio << -123 << ", " << 0 << ", " << 123 << sio.nl;
13
14 sio << "+----------+" << sio.nl;
15 sio << "|" << Fmt( 10, 10, Fmt::Center ) << "Test" << "|" << sio.nl;
16 sio << "+----------+" << sio.nl;
17 sio << "|" << Fmt( 10, 10, Fmt::Left ) << 123 << "|" << sio.nl;
18 sio << "|" << Fmt( 10, 10, Fmt::Center ) << 123 << "|" << sio.nl;
19 sio << "|" << Fmt( 10, 10, Fmt::Right ) << 123 << "|" << sio.nl;
20 sio << "+----------+" << sio.nl;
6 21
7 Bu::sio << "sizeof(Fmt) = " << sizeof(Bu::Fmt) << Bu::sio.nl; 22 sio << Fmt(10,Fmt::Left) << "Hexcode:" << Fmt::ptr() << (&sio) << sio.nl;
8 23
9 Bu::sio << -123 << ", " << 0 << ", " << 123 << Bu::sio.nl; 24 sio << 0.123 << sio.nl;
25 sio << true << " and then " << false << sio.nl;
10 26
11 Bu::sio << "+----------+" << Bu::sio.nl; 27 //for( int j = 2; j <= 36; j++ )
12 Bu::sio << "|" << Bu::Fmt( 10, 10, Bu::Fmt::Center ) << "Test" << "|" << Bu::sio.nl; 28 // sio << "radix(" << j << ") = " << Fmt().radix( j ) << 255 << sio.nl;
13 Bu::sio << "+----------+" << Bu::sio.nl;
14 Bu::sio << "|" << Bu::Fmt( 10, 10, Bu::Fmt::Left ) << 123 << "|" << Bu::sio.nl;
15 Bu::sio << "|" << Bu::Fmt( 10, 10, Bu::Fmt::Center ) << 123 << "|" << Bu::sio.nl;
16 Bu::sio << "|" << Bu::Fmt( 10, 10, Bu::Fmt::Right ) << 123 << "|" << Bu::sio.nl;
17 Bu::sio << "+----------+" << Bu::sio.nl;
18 29
19 return 0; 30 return 0;
20} 31}
diff --git a/src/uuid.cpp b/src/uuid.cpp
new file mode 100644
index 0000000..8a30e2a
--- /dev/null
+++ b/src/uuid.cpp
@@ -0,0 +1,18 @@
1#include "bu/uuid.h"
2
3Bu::Uuid::Uuid()
4{
5 clear();
6}
7
8Bu::Uuid::~Uuid()
9{
10}
11
12#define msb( i ) (1<<(7-i))
13
14void Bu::Uuid::clear()
15{
16 data[7] = msb(0);
17}
18
diff --git a/src/uuid.h b/src/uuid.h
new file mode 100644
index 0000000..2bb1404
--- /dev/null
+++ b/src/uuid.h
@@ -0,0 +1,25 @@
1#ifndef BU_UUID_H
2#define BU_UUID_H
3
4namespace Bu
5{
6 class Uuid
7 {
8 public:
9 Uuid();
10 virtual ~Uuid();
11
12 static Uuid genV1();
13 static Uuid genV2();
14 static Uuid genV3();
15 static Uuid genV4();
16 static Uuid genV5();
17
18 void clear();
19
20 private:
21 unsigned char data[8];
22 };
23};
24
25#endif