1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.juddi.uuidgen;
17
18 import java.math.BigInteger;
19 import java.util.Random;
20
21 /***
22 * Used to create new universally unique identifiers or UUID's (sometimes called
23 * GUID's). UDDI UUID's are allways formmated according to DCE UUID conventions.
24 *
25 * @author Maarten Coene
26 * @author Steve Viens (sviens@apache.org)
27 */
28 public class DefaultUUIDGen implements UUIDGen
29 {
30 private static final BigInteger COUNT_START = new BigInteger("-12219292800000");
31 private static final int CLOCK_SEQUENCE = (new Random()).nextInt(16384);
32
33 private Random random;
34
35 /***
36 *
37 */
38 public DefaultUUIDGen()
39 {
40 try {
41 random = new Random();
42 random.setSeed(System.currentTimeMillis());
43 } catch (Exception e) {
44 random = new Random();
45 }
46 }
47
48 /***
49 *
50 */
51 public String uuidgen()
52 {
53 return nextUUID();
54 }
55
56 /***
57 *
58 */
59 public String[] uuidgen(int nmbr)
60 {
61 String[] uuids = new String[nmbr];
62
63 for (int i=0; i<uuids.length; i++)
64 uuids[i] = nextUUID();
65
66 return uuids;
67 }
68
69 /***
70 * Creates a new UUID. The algorithm used is described by The Open Group.
71 * See <a href="http://www.opengroup.org/onlinepubs/009629399/apdxa.htm">
72 * Universal Unique Identifier</a> for more details.
73 *
74 * Due to a lack of functionality in Java, a part of the UUID is a secure
75 * random. This results in a long processing time when this method is called
76 * for the first time.
77 */
78 private String nextUUID()
79 {
80
81 BigInteger current = BigInteger.valueOf(System.currentTimeMillis());
82
83
84 BigInteger countMillis = current.subtract(COUNT_START);
85
86
87 BigInteger count = countMillis.multiply(BigInteger.valueOf(10000));
88
89 String bitString = count.toString(2);
90 if (bitString.length() < 60)
91 {
92 int nbExtraZeros = 60 - bitString.length();
93 String extraZeros = new String();
94 for (int i=0; i<nbExtraZeros; i++)
95 extraZeros = extraZeros.concat("0");
96
97 bitString = extraZeros.concat(bitString);
98 }
99
100 byte[] bits = bitString.getBytes();
101
102
103 byte[] time_low = new byte[32];
104 for (int i=0; i<32; i++)
105 time_low[i] = bits[bits.length - i - 1];
106
107
108 byte[] time_mid = new byte[16];
109 for (int i=0; i<16; i++)
110 time_mid[i] = bits[bits.length - 32 - i - 1];
111
112
113 byte[] time_hi_and_version = new byte[16];
114 for (int i=0; i<12; i++)
115 time_hi_and_version[i] = bits[bits.length - 48 - i - 1];
116
117 time_hi_and_version[12] = ((new String("1")).getBytes())[0];
118 time_hi_and_version[13] = ((new String("0")).getBytes())[0];
119 time_hi_and_version[14] = ((new String("0")).getBytes())[0];
120 time_hi_and_version[15] = ((new String("0")).getBytes())[0];
121
122
123 BigInteger clockSequence = BigInteger.valueOf(CLOCK_SEQUENCE);
124 String clockString = clockSequence.toString(2);
125 if (clockString.length() < 14)
126 {
127 int nbExtraZeros = 14 - bitString.length();
128 String extraZeros = new String();
129 for (int i=0; i<nbExtraZeros; i++)
130 extraZeros = extraZeros.concat("0");
131
132 clockString = extraZeros.concat(bitString);
133 }
134
135 byte[] clock_bits = clockString.getBytes();
136 byte[] clock_seq_low = new byte[8];
137 for (int i=0; i<8; i++)
138 clock_seq_low[i] = clock_bits[clock_bits.length - i - 1];
139
140
141 byte[] clock_seq_hi_and_reserved = new byte[8];
142 for (int i=0; i<6; i++)
143 clock_seq_hi_and_reserved[i] = clock_bits[clock_bits.length - 8 - i - 1];
144
145 clock_seq_hi_and_reserved[6] = ((new String("0")).getBytes())[0];
146 clock_seq_hi_and_reserved[7] = ((new String("1")).getBytes())[0];
147
148 String timeLow = Long.toHexString((new BigInteger(new String(reverseArray(time_low)), 2)).longValue());
149 if (timeLow.length() < 8)
150 {
151 int nbExtraZeros = 8 - timeLow.length();
152 String extraZeros = new String();
153 for (int i=0; i<nbExtraZeros; i++)
154 extraZeros = extraZeros.concat("0");
155
156 timeLow = extraZeros.concat(timeLow);
157 }
158
159 String timeMid = Long.toHexString((new BigInteger(new String(reverseArray(time_mid)), 2)).longValue());
160 if (timeMid.length() < 4)
161 {
162 int nbExtraZeros = 4 - timeMid.length();
163 String extraZeros = new String();
164 for (int i=0; i<nbExtraZeros; i++)
165 extraZeros = extraZeros.concat("0");
166
167 timeMid = extraZeros.concat(timeMid);
168 }
169
170 String timeHiAndVersion = Long.toHexString((new BigInteger(new String(reverseArray(time_hi_and_version)), 2)).longValue());
171 if (timeHiAndVersion.length() < 4)
172 {
173 int nbExtraZeros = 4 - timeHiAndVersion.length();
174 String extraZeros = new String();
175 for (int i=0; i<nbExtraZeros; i++)
176 extraZeros = extraZeros.concat("0");
177
178 timeHiAndVersion = extraZeros.concat(timeHiAndVersion);
179 }
180
181 String clockSeqHiAndReserved = Long.toHexString((new BigInteger(new String(reverseArray(clock_seq_hi_and_reserved)), 2)).longValue());
182 if (clockSeqHiAndReserved.length() < 2)
183 {
184 int nbExtraZeros = 2 - clockSeqHiAndReserved.length();
185 String extraZeros = new String();
186 for (int i=0; i<nbExtraZeros; i++)
187 extraZeros = extraZeros.concat("0");
188
189 clockSeqHiAndReserved = extraZeros.concat(clockSeqHiAndReserved);
190 }
191
192 String clockSeqLow = Long.toHexString((new BigInteger(new String(reverseArray(clock_seq_low)), 2)).longValue());
193 if (clockSeqLow.length() < 2)
194 {
195 int nbExtraZeros = 2 - clockSeqLow.length();
196 String extraZeros = new String();
197 for (int i=0; i<nbExtraZeros; i++)
198 extraZeros = extraZeros.concat("0");
199
200 clockSeqLow = extraZeros.concat(clockSeqLow);
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 long nodeValue = random.nextLong();
219 nodeValue = Math.abs(nodeValue);
220 while (nodeValue > 140737488355328L)
221 {
222 nodeValue = random.nextLong();
223 nodeValue = Math.abs(nodeValue);
224 }
225
226 BigInteger nodeInt = BigInteger.valueOf(nodeValue);
227 String nodeString = nodeInt.toString(2);
228 if (nodeString.length() < 47)
229 {
230 int nbExtraZeros = 47 - nodeString.length();
231 String extraZeros = new String();
232 for (int i=0; i<nbExtraZeros; i++)
233 extraZeros = extraZeros.concat("0");
234
235 nodeString = extraZeros.concat(nodeString);
236 }
237
238 byte[] node_bits = nodeString.getBytes();
239 byte[] node = new byte[48];
240 for (int i=0; i<47; i++)
241 node[i] = node_bits[node_bits.length - i - 1];
242
243 node[47] = ((new String("1")).getBytes())[0];
244 String theNode = Long.toHexString((new BigInteger(new String(reverseArray(node)), 2)).longValue());
245 if (theNode.length() < 12)
246 {
247 int nbExtraZeros = 12 - theNode.length();
248 String extraZeros = new String();
249 for (int i=0; i<nbExtraZeros; i++)
250 extraZeros = extraZeros.concat("0");
251 theNode = extraZeros.concat(theNode);
252 }
253
254 String result = timeLow + "-" + timeMid +"-" + timeHiAndVersion + "-" + clockSeqHiAndReserved + clockSeqLow + "-" + theNode;
255
256 return result.toUpperCase();
257 }
258
259 /***
260 *
261 */
262 private static byte[] reverseArray(byte[] bits)
263 {
264 byte[] result = new byte[bits.length];
265 for (int i=0; i<result.length; i++)
266 result[i] = bits[result.length - 1 - i];
267
268 return result;
269 }
270
271
272 /****************************************************************************/
273 /****************************** TEST DRIVER *********************************/
274 /****************************************************************************/
275
276
277 public static void main(String args[])
278 {
279 DefaultUUIDGen generator = new DefaultUUIDGen();
280
281 long start = System.currentTimeMillis();
282
283 for (int i = 1; i <= 100; ++i)
284 generator.uuidgen();
285
286 long end = System.currentTimeMillis();
287
288 System.out.println("DefaultUUIDGen: Generation of 100 UUID's took "+(end-start)+" milliseconds.");
289 }
290 }