wheee!
[asdcplib.git] / AS_DCP_UUID.cpp
1 /*
2 Copyright (c) 2005, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 /*! \file    AS_DCP_UUID.cpp
28     \version $Id$
29     \brief   Miscellaneous timecode functions
30 */
31
32 #include <AS_DCP_UUID.h>
33 #include <assert.h>
34
35
36 static FortunaRNG s_RNG;
37
38 using namespace ASDCP;
39
40
41 // given a 16 byte buffer, this subroutine uses the given RNG to generate a
42 // random value, and sets the necessary bits to turn the value into a proper UUID per
43 // sec. 4.4 of http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-03.txt
44 // Parts of that document are reprinted here for your convenience:
45 //
46 // 0                   1                   2                   3
47 // 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
48 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 // |                          time_low                             |
50 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 // |       time_mid                |         time_hi_and_version   |
52 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 // |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |
54 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 // |                         node (2-5)                            |
56 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 //
58 //     Msb0  Msb1  Msb2  Msb3   Version  Description
59 //
60 //      0     1     0     0        4     The randomly or pseudo-
61 //                                       randomly generated version
62 //                                       specified in this document.
63 //
64 //  o  Set the two most significant bits (bits six and seven) of the
65 //     clock_seq_hi_and_reserved to zero and one, respectively.
66 //  o  Set the four most significant bits (bits 12 through 15) of the
67 //     time_hi_and_version field to the four-bit version number from
68 //     Section 4.1.3.
69 //  o  Set all the other bits to randomly (or pseudo-randomly) chosen
70 //     values.
71 //
72
73 // fill buffer with random bits and set appropriate UUID flags
74 void
75 ASDCP::GenRandomUUID(FortunaRNG& RNG, byte_t* buf)
76 {
77   assert(buf);
78   RNG.FillRandom(buf, UUIDlen);
79   buf[6] &= 0x0f; // clear bits 4-7
80   buf[6] |= 0x40; // set UUID version
81   buf[8] &= 0x3f; // clear bits 6&7
82   buf[8] |= 0x80; // set bit 7
83 }
84
85 // add UUID hyphens to 32 character hexadecimal string
86 char*
87 ASDCP::hyphenate_UUID(char* str_buf, ui32_t buf_len)
88 {
89   ui32_t i, j, k;
90
91   assert(str_buf);
92   assert (buf_len > 36);
93
94   // shift the node id
95   for ( k = 19, i = 12; i > 0; i-- )
96     str_buf[k+i+4] = str_buf[k+i];
97
98   // shift the time (mid+hi+clk)
99   for ( k = 15, j = 3; k > 6; k -= 4, j-- )
100     {
101       for ( i = 4; i > 0; i-- )
102         str_buf[k+i+j] = str_buf[k+i];
103     }
104
105   // add in the hyphens and trainling null
106   for ( i = 8; i < 24; i += 5 )
107     str_buf[i] = '-';
108   
109   str_buf[36] = 0;
110   return str_buf;
111 }
112
113
114 //
115 void
116 ASDCP::MakeUUID(byte_t* buf)
117 {
118   GenRandomUUID(s_RNG, buf);
119 }
120
121
122
123 //
124 // end AS_DCP_UUID.cpp
125 //