History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/util/UUID.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/util/UUID.java+443−0
@@ -0,0 +1,443 @@
1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.util;
27
28import java.security.*;
29
30/**
31 * A class that represents an immutable universally unique identifier (UUID).
32 * A UUID represents a 128-bit value.
33 *
34 * <p> There exist different variants of these global identifiers. The methods
35 * of this class are for manipulating the Leach-Salz variant, although the
36 * constructors allow the creation of any variant of UUID (described below).
37 *
38 * <p> The layout of a variant 2 (Leach-Salz) UUID is as follows:
39 *
40 * The most significant long consists of the following unsigned fields:
41 * <pre>
42 * 0xFFFFFFFF00000000 time_low
43 * 0x00000000FFFF0000 time_mid
44 * 0x000000000000F000 version
45 * 0x0000000000000FFF time_hi
46 * </pre>
47 * The least significant long consists of the following unsigned fields:
48 * <pre>
49 * 0xC000000000000000 variant
50 * 0x3FFF000000000000 clock_seq
51 * 0x0000FFFFFFFFFFFF node
52 * </pre>
53 *
54 * <p> The variant field contains a value which identifies the layout of the
55 * {@code UUID}. The bit layout described above is valid only for a {@code
56 * UUID} with a variant value of 2, which indicates the Leach-Salz variant.
57 *
58 * <p> The version field holds a value that describes the type of this {@code
59 * UUID}. There are four different basic types of UUIDs: time-based, DCE
60 * security, name-based, and randomly generated UUIDs. These types have a
61 * version value of 1, 2, 3 and 4, respectively.
62 *
63 * <p> For more information including algorithms used to create {@code UUID}s,
64 * see <a href="http://www.ietf.org/rfc/rfc4122.txt"> <i>RFC&nbsp;4122: A
65 * Universally Unique IDentifier (UUID) URN Namespace</i></a>, section 4.2
66 * &quot;Algorithms for Creating a Time-Based UUID&quot;.
67 *
68 * @since 1.5
69 */
70public final class UUID implements java.io.Serializable, Comparable<UUID> {
71
72 /**
73 * Explicit serialVersionUID for interoperability.
74 */
75 private static final long serialVersionUID = -4856846361193249489L;
76
77 /*
78 * The most significant 64 bits of this UUID.
79 *
80 * @serial
81 */
82 private final long mostSigBits;
83
84 /*
85 * The least significant 64 bits of this UUID.
86 *
87 * @serial
88 */
89 private final long leastSigBits;
90
91 /*
92 * The random number generator used by this class to create random
93 * based UUIDs.
94 */
95 private static volatile SecureRandom numberGenerator = null;
96
97 // Constructors and Factories
98
99 /*
100 * Private constructor which uses a byte array to construct the new UUID.
101 */
102 private UUID(byte[] data) {
103 long msb = 0;
104 long lsb = 0;
105 assert data.length == 16 : "data must be 16 bytes in length";
106 for (int i=0; i<8; i++)
107 msb = (msb << 8) | (data[i] & 0xff);
108 for (int i=8; i<16; i++)
109 lsb = (lsb << 8) | (data[i] & 0xff);
110 this.mostSigBits = msb;
111 this.leastSigBits = lsb;
112 }
113
114 /**
115 * Constructs a new {@code UUID} using the specified data. {@code
116 * mostSigBits} is used for the most significant 64 bits of the {@code
117 * UUID} and {@code leastSigBits} becomes the least significant 64 bits of
118 * the {@code UUID}.
119 *
120 * @param mostSigBits
121 * The most significant bits of the {@code UUID}
122 *
123 * @param leastSigBits
124 * The least significant bits of the {@code UUID}
125 */
126 public UUID(long mostSigBits, long leastSigBits) {
127 this.mostSigBits = mostSigBits;
128 this.leastSigBits = leastSigBits;
129 }
130
131 /**
132 * Static factory to retrieve a type 4 (pseudo randomly generated) UUID.
133 *
134 * The {@code UUID} is generated using a cryptographically strong pseudo
135 * random number generator.
136 *
137 * @return A randomly generated {@code UUID}
138 */
139 public static UUID randomUUID() {
140 SecureRandom ng = numberGenerator;
141 if (ng == null) {
142 numberGenerator = ng = new SecureRandom();
143 }
144
145 byte[] randomBytes = new byte[16];
146 ng.nextBytes(randomBytes);
147 randomBytes[6] &= 0x0f; /* clear version */
148 randomBytes[6] |= 0x40; /* set to version 4 */
149 randomBytes[8] &= 0x3f; /* clear variant */
150 randomBytes[8] |= 0x80; /* set to IETF variant */
151 return new UUID(randomBytes);
152 }
153
154 /**
155 * Static factory to retrieve a type 3 (name based) {@code UUID} based on
156 * the specified byte array.
157 *
158 * @param name
159 * A byte array to be used to construct a {@code UUID}
160 *
161 * @return A {@code UUID} generated from the specified array
162 */
163 public static UUID nameUUIDFromBytes(byte[] name) {
164 MessageDigest md;
165 try {
166 md = MessageDigest.getInstance("MD5");
167 } catch (NoSuchAlgorithmException nsae) {
168 throw new InternalError("MD5 not supported");
169 }
170 byte[] md5Bytes = md.digest(name);
171 md5Bytes[6] &= 0x0f; /* clear version */
172 md5Bytes[6] |= 0x30; /* set to version 3 */
173 md5Bytes[8] &= 0x3f; /* clear variant */
174 md5Bytes[8] |= 0x80; /* set to IETF variant */
175 return new UUID(md5Bytes);
176 }
177
178 /**
179 * Creates a {@code UUID} from the string standard representation as
180 * described in the {@link #toString} method.
181 *
182 * @param name
183 * A string that specifies a {@code UUID}
184 *
185 * @return A {@code UUID} with the specified value
186 *
187 * @throws IllegalArgumentException
188 * If name does not conform to the string representation as
189 * described in {@link #toString}
190 *
191 */
192 public static UUID fromString(String name) {
193 String[] components = name.split("-");
194 if (components.length != 5)
195 throw new IllegalArgumentException("Invalid UUID string: "+name);
196 for (int i=0; i<5; i++)
197 components[i] = "0x"+components[i];
198
199 long mostSigBits = Long.decode(components[0]).longValue();
200 mostSigBits <<= 16;
201 mostSigBits |= Long.decode(components[1]).longValue();
202 mostSigBits <<= 16;
203 mostSigBits |= Long.decode(components[2]).longValue();
204
205 long leastSigBits = Long.decode(components[3]).longValue();
206 leastSigBits <<= 48;
207 leastSigBits |= Long.decode(components[4]).longValue();
208
209 return new UUID(mostSigBits, leastSigBits);
210 }
211
212 // Field Accessor Methods
213
214 /**
215 * Returns the least significant 64 bits of this UUID's 128 bit value.
216 *
217 * @return The least significant 64 bits of this UUID's 128 bit value
218 */
219 public long getLeastSignificantBits() {
220 return leastSigBits;
221 }
222
223 /**
224 * Returns the most significant 64 bits of this UUID's 128 bit value.
225 *
226 * @return The most significant 64 bits of this UUID's 128 bit value
227 */
228 public long getMostSignificantBits() {
229 return mostSigBits;
230 }
231
232 /**
233 * The version number associated with this {@code UUID}. The version
234 * number describes how this {@code UUID} was generated.
235 *
236 * The version number has the following meaning:
237 * <p><ul>
238 * <li>1 Time-based UUID
239 * <li>2 DCE security UUID
240 * <li>3 Name-based UUID
241 * <li>4 Randomly generated UUID
242 * </ul>
243 *
244 * @return The version number of this {@code UUID}
245 */
246 public int version() {
247 // Version is bits masked by 0x000000000000F000 in MS long
248 return (int)((mostSigBits >> 12) & 0x0f);
249 }
250
251 /**
252 * The variant number associated with this {@code UUID}. The variant
253 * number describes the layout of the {@code UUID}.
254 *
255 * The variant number has the following meaning:
256 * <p><ul>
257 * <li>0 Reserved for NCS backward compatibility
258 * <li>2 The Leach-Salz variant (used by this class)
259 * <li>6 Reserved, Microsoft Corporation backward compatibility
260 * <li>7 Reserved for future definition
261 * </ul>
262 *
263 * @return The variant number of this {@code UUID}
264 */
265 public int variant() {
266 // This field is composed of a varying number of bits.
267 // 0 - - Reserved for NCS backward compatibility
268 // 1 0 - The Leach-Salz variant (used by this class)
269 // 1 1 0 Reserved, Microsoft backward compatibility
270 // 1 1 1 Reserved for future definition.
271 return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62)))
272 & (leastSigBits >> 63));
273 }
274
275 /**
276 * The timestamp value associated with this UUID.
277 *
278 * <p> The 60 bit timestamp value is constructed from the time_low,
279 * time_mid, and time_hi fields of this {@code UUID}. The resulting
280 * timestamp is measured in 100-nanosecond units since midnight,
281 * October 15, 1582 UTC.
282 *
283 * <p> The timestamp value is only meaningful in a time-based UUID, which
284 * has version type 1. If this {@code UUID} is not a time-based UUID then
285 * this method throws UnsupportedOperationException.
286 *
287 * @throws UnsupportedOperationException
288 * If this UUID is not a version 1 UUID
289 */
290 public long timestamp() {
291 if (version() != 1) {
292 throw new UnsupportedOperationException("Not a time-based UUID");
293 }
294
295 return (mostSigBits & 0x0FFFL) << 48
296 | ((mostSigBits >> 16) & 0x0FFFFL) << 32
297 | mostSigBits >>> 32;
298 }
299
300 /**
301 * The clock sequence value associated with this UUID.
302 *
303 * <p> The 14 bit clock sequence value is constructed from the clock
304 * sequence field of this UUID. The clock sequence field is used to
305 * guarantee temporal uniqueness in a time-based UUID.
306 *
307 * <p> The {@code clockSequence} value is only meaningful in a time-based
308 * UUID, which has version type 1. If this UUID is not a time-based UUID
309 * then this method throws UnsupportedOperationException.
310 *
311 * @return The clock sequence of this {@code UUID}
312 *
313 * @throws UnsupportedOperationException
314 * If this UUID is not a version 1 UUID
315 */
316 public int clockSequence() {
317 if (version() != 1) {
318 throw new UnsupportedOperationException("Not a time-based UUID");
319 }
320
321 return (int)((leastSigBits & 0x3FFF000000000000L) >>> 48);
322 }
323
324 /**
325 * The node value associated with this UUID.
326 *
327 * <p> The 48 bit node value is constructed from the node field of this
328 * UUID. This field is intended to hold the IEEE 802 address of the machine
329 * that generated this UUID to guarantee spatial uniqueness.
330 *
331 * <p> The node value is only meaningful in a time-based UUID, which has
332 * version type 1. If this UUID is not a time-based UUID then this method
333 * throws UnsupportedOperationException.
334 *
335 * @return The node value of this {@code UUID}
336 *
337 * @throws UnsupportedOperationException
338 * If this UUID is not a version 1 UUID
339 */
340 public long node() {
341 if (version() != 1) {
342 throw new UnsupportedOperationException("Not a time-based UUID");
343 }
344
345 return leastSigBits & 0x0000FFFFFFFFFFFFL;
346 }
347
348 // Object Inherited Methods
349
350 /**
351 * Returns a {@code String} object representing this {@code UUID}.
352 *
353 * <p> The UUID string representation is as described by this BNF:
354 * <blockquote><pre>
355 * {@code
356 * UUID = <time_low> "-" <time_mid> "-"
357 * <time_high_and_version> "-"
358 * <variant_and_sequence> "-"
359 * <node>
360 * time_low = 4*<hexOctet>
361 * time_mid = 2*<hexOctet>
362 * time_high_and_version = 2*<hexOctet>
363 * variant_and_sequence = 2*<hexOctet>
364 * node = 6*<hexOctet>
365 * hexOctet = <hexDigit><hexDigit>
366 * hexDigit =
367 * "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
368 * | "a" | "b" | "c" | "d" | "e" | "f"
369 * | "A" | "B" | "C" | "D" | "E" | "F"
370 * }</pre></blockquote>
371 *
372 * @return A string representation of this {@code UUID}
373 */
374 public String toString() {
375 return (digits(mostSigBits >> 32, 8) + "-" +
376 digits(mostSigBits >> 16, 4) + "-" +
377 digits(mostSigBits, 4) + "-" +
378 digits(leastSigBits >> 48, 4) + "-" +
379 digits(leastSigBits, 12));
380 }
381
382 /** Returns val represented by the specified number of hex digits. */
383 private static String digits(long val, int digits) {
384 long hi = 1L << (digits * 4);
385 return Long.toHexString(hi | (val & (hi - 1))).substring(1);
386 }
387
388 /**
389 * Returns a hash code for this {@code UUID}.
390 *
391 * @return A hash code value for this {@code UUID}
392 */
393 public int hashCode() {
394 long hilo = mostSigBits ^ leastSigBits;
395 return ((int)(hilo >> 32)) ^ (int) hilo;
396 }
397
398 /**
399 * Compares this object to the specified object. The result is {@code
400 * true} if and only if the argument is not {@code null}, is a {@code UUID}
401 * object, has the same variant, and contains the same value, bit for bit,
402 * as this {@code UUID}.
403 *
404 * @param obj
405 * The object to be compared
406 *
407 * @return {@code true} if the objects are the same; {@code false}
408 * otherwise
409 */
410 public boolean equals(Object obj) {
411 if ((null == obj) || (obj.getClass() != UUID.class))
412 return false;
413 UUID id = (UUID)obj;
414 return (mostSigBits == id.mostSigBits &&
415 leastSigBits == id.leastSigBits);
416 }
417
418 // Comparison Operations
419
420 /**
421 * Compares this UUID with the specified UUID.
422 *
423 * <p> The first of two UUIDs is greater than the second if the most
424 * significant field in which the UUIDs differ is greater for the first
425 * UUID.
426 *
427 * @param val
428 * {@code UUID} to which this {@code UUID} is to be compared
429 *
430 * @return -1, 0 or 1 as this {@code UUID} is less than, equal to, or
431 * greater than {@code val}
432 *
433 */
434 public int compareTo(UUID val) {
435 // The ordering is intentionally set up so that the UUIDs
436 // can simply be numerically compared as two numbers
437 return (this.mostSigBits < val.mostSigBits ? -1 :
438 (this.mostSigBits > val.mostSigBits ? 1 :
439 (this.leastSigBits < val.leastSigBits ? -1 :
440 (this.leastSigBits > val.leastSigBits ? 1 :
441 0))));
442 }
443}