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
26 package java.util;
27
28 import 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
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 4122: A
65 * Universally Unique IDentifier (UUID) URN Namespace</i></a>, section 4.2
66 * "Algorithms for Creating a Time-Based UUID".
67 *
68 * @since 1.5
69 */
70 public 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. In a holder class to defer initialization until needed.
94 */
95 private static class Holder {
96 static final SecureRandom numberGenerator = new SecureRandom();
161 */
162 public static UUID nameUUIDFromBytes(byte[] name) {
163 MessageDigest md;
164 try {
165 md = MessageDigest.getInstance("MD5");
166 } catch (NoSuchAlgorithmException nsae) {
167 throw new InternalError("MD5 not supported", nsae);
168 }
169 byte[] md5Bytes = md.digest(name);
170 md5Bytes[6] &= 0x0f; /* clear version */
171 md5Bytes[6] |= 0x30; /* set to version 3 */
172 md5Bytes[8] &= 0x3f; /* clear variant */
173 md5Bytes[8] |= 0x80; /* set to IETF variant */
174 return new UUID(md5Bytes);
175 }
176
177 /**
178 * Creates a {@code UUID} from the string standard representation as
179 * described in the {@link #toString} method.
180 *
181 * @param name
182 * A string that specifies a {@code UUID}
183 *
184 * @return A {@code UUID} with the specified value
185 *
186 * @throws IllegalArgumentException
187 * If name does not conform to the string representation as
188 * described in {@link #toString}
189 *
190 */
191 public static UUID fromString(String name) {
192 String[] components = name.split("-");
193 if (components.length != 5)
194 throw new IllegalArgumentException("Invalid UUID string: "+name);
195 for (int i=0; i<5; i++)
196 components[i] = "0x"+components[i];
197
198 long mostSigBits = Long.decode(components[0]).longValue();
199 mostSigBits <<= 16;
200 mostSigBits |= Long.decode(components[1]).longValue();
201 mostSigBits <<= 16;
202 mostSigBits |= Long.decode(components[2]).longValue();
203
204 long leastSigBits = Long.decode(components[3]).longValue();
205 leastSigBits <<= 48;
206 leastSigBits |= Long.decode(components[4]).longValue();
207
208 return new UUID(mostSigBits, leastSigBits);
209 }
210
211 // Field Accessor Methods
212
213 /**
214 * Returns the least significant 64 bits of this UUID's 128 bit value.
215 *
216 * @return The least significant 64 bits of this UUID's 128 bit value
217 */
218 public long getLeastSignificantBits() {
219 return leastSigBits;
220 }
221
222 /**
223 * Returns the most significant 64 bits of this UUID's 128 bit value.
224 *
225 * @return The most significant 64 bits of this UUID's 128 bit value
226 */
227 public long getMostSignificantBits() {
228 return mostSigBits;
229 }
230
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
|
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
26 package java.util;
27
28 import java.security.*;
29
30 import sun.misc.JavaLangAccess;
31 import sun.misc.SharedSecrets;
32
33 /**
34 * A class that represents an immutable universally unique identifier (UUID).
35 * A UUID represents a 128-bit value.
36 *
37 * <p> There exist different variants of these global identifiers. The methods
38 * of this class are for manipulating the Leach-Salz variant, although the
39 * constructors allow the creation of any variant of UUID (described below).
40 *
41 * <p> The layout of a variant 2 (Leach-Salz) UUID is as follows:
42 *
43 * The most significant long consists of the following unsigned fields:
44 * <pre>
45 * 0xFFFFFFFF00000000 time_low
46 * 0x00000000FFFF0000 time_mid
47 * 0x000000000000F000 version
48 * 0x0000000000000FFF time_hi
49 * </pre>
50 * The least significant long consists of the following unsigned fields:
51 * <pre>
52 * 0xC000000000000000 variant
60 *
61 * <p> The version field holds a value that describes the type of this {@code
62 * UUID}. There are four different basic types of UUIDs: time-based, DCE
63 * security, name-based, and randomly generated UUIDs. These types have a
64 * version value of 1, 2, 3 and 4, respectively.
65 *
66 * <p> For more information including algorithms used to create {@code UUID}s,
67 * see <a href="http://www.ietf.org/rfc/rfc4122.txt"> <i>RFC 4122: A
68 * Universally Unique IDentifier (UUID) URN Namespace</i></a>, section 4.2
69 * "Algorithms for Creating a Time-Based UUID".
70 *
71 * @since 1.5
72 */
73 public final class UUID implements java.io.Serializable, Comparable<UUID> {
74
75 /**
76 * Explicit serialVersionUID for interoperability.
77 */
78 private static final long serialVersionUID = -4856846361193249489L;
79
80 /**
81 * Provides access to String's non-public constructor that does not copy the char[]
82 */
83 private static final JavaLangAccess JAVA_LANG_ACCESS
84 = SharedSecrets.getJavaLangAccess();
85
86 /*
87 * The most significant 64 bits of this UUID.
88 *
89 * @serial
90 */
91 private final long mostSigBits;
92
93 /*
94 * The least significant 64 bits of this UUID.
95 *
96 * @serial
97 */
98 private final long leastSigBits;
99
100 /*
101 * The random number generator used by this class to create random
102 * based UUIDs. In a holder class to defer initialization until needed.
103 */
104 private static class Holder {
105 static final SecureRandom numberGenerator = new SecureRandom();
170 */
171 public static UUID nameUUIDFromBytes(byte[] name) {
172 MessageDigest md;
173 try {
174 md = MessageDigest.getInstance("MD5");
175 } catch (NoSuchAlgorithmException nsae) {
176 throw new InternalError("MD5 not supported", nsae);
177 }
178 byte[] md5Bytes = md.digest(name);
179 md5Bytes[6] &= 0x0f; /* clear version */
180 md5Bytes[6] |= 0x30; /* set to version 3 */
181 md5Bytes[8] &= 0x3f; /* clear variant */
182 md5Bytes[8] |= 0x80; /* set to IETF variant */
183 return new UUID(md5Bytes);
184 }
185
186 /**
187 * Creates a {@code UUID} from the string standard representation as
188 * described in the {@link #toString} method.
189 *
190 * @param str
191 * A string that specifies a {@code UUID}
192 *
193 * @return A {@code UUID} with the specified value
194 *
195 * @throws IllegalArgumentException
196 * If name does not conform to the string representation as
197 * described in {@link #toString}
198 *
199 */
200 public static UUID fromString(String str) {
201 int dashCount = 4;
202 int [] dashPos = new int [6];
203 dashPos[0] = -1;
204 dashPos[5] = str.length();
205
206 for (int i = str.length()-1; i >= 0; i--) {
207 if (str.charAt(i) == '-') {
208 if (dashCount == 0) {
209 throw new IllegalArgumentException("Invalid UUID string: " + str);
210 }
211 dashPos[dashCount--] = i;
212 }
213 }
214
215 if (dashCount > 0) {
216 throw new IllegalArgumentException("Invalid UUID string: " + str);
217 }
218
219 long mostSigBits = decode(str, dashPos, 0) & 0xffffffffL;
220 mostSigBits <<= 16;
221 mostSigBits |= decode(str, dashPos, 1) & 0xffffL;
222 mostSigBits <<= 16;
223 mostSigBits |= decode(str, dashPos, 2) & 0xffffL;
224
225 long leastSigBits = decode(str, dashPos, 3) & 0xffffL;
226 leastSigBits <<= 48;
227 leastSigBits |= decode(str, dashPos, 4) & 0xffffffffffffL;
228
229 return new UUID(mostSigBits, leastSigBits);
230 }
231
232 private static long decode(final String str, final int [] dashPos, final int field) {
233 int start = dashPos[field]+1;
234 int end = dashPos[field+1];
235 if (start >= end) {
236 throw new IllegalArgumentException("Invalid UUID string: " + str);
237 }
238 return decodeLongHexString(str, start, end);
239 }
240
241 private static final int NUM_ALPHA_DIFF = 'A' - '9' - 1;
242 private static final int LOWER_UPPER_DIFF = 'a' - 'A';
243
244 /**
245 * Given a hexadecimal string, decode a portion into a long.
246 * @param str the string to decode
247 * @param start the start of the substring to decode
248 * @param end the end of the substring to decode
249 */
250 public static long decodeLongHexString(CharSequence str, int start, int end)
251 {
252 long curr = 0;
253 for (int i = start; i < end; i++) {
254 int x = getNibbleFromHexChar(str.charAt(i));
255 curr <<= 4;
256 if (curr < 0) {
257 throw new NumberFormatException("long overflow");
258 }
259 curr |= x;
260 }
261 return curr;
262 }
263
264 /**
265 * Given a hexadecimal digit, return the decimal value.
266 * @param c the character to decode
267 */
268 public static int getNibbleFromHexChar(final char c)
269 {
270 int x = c - '0';
271 if (x > 9) {
272 x -= NUM_ALPHA_DIFF; // difference between '9' and 'A'
273 if (x > 15) {
274 x -= LOWER_UPPER_DIFF; // difference between 'a' and 'A'
275 }
276 if (x < 10) {
277 throw new IllegalArgumentException(c + " is not a valid character for a hex string");
278 }
279 }
280
281 if (x < 0 || x > 15) {
282 throw new IllegalArgumentException(c + " is not a valid character for a hex string");
283 }
284
285 return x;
286 }
287
288 // Field Accessor Methods
289
290 /**
291 * Returns the least significant 64 bits of this UUID's 128 bit value.
292 *
293 * @return The least significant 64 bits of this UUID's 128 bit value
294 */
295 public long getLeastSignificantBits() {
296 return leastSigBits;
297 }
298
299 /**
300 * Returns the most significant 64 bits of this UUID's 128 bit value.
301 *
302 * @return The most significant 64 bits of this UUID's 128 bit value
303 */
304 public long getMostSignificantBits() {
305 return mostSigBits;
306 }
307
431 * <blockquote><pre>
432 * {@code
433 * UUID = <time_low> "-" <time_mid> "-"
434 * <time_high_and_version> "-"
435 * <variant_and_sequence> "-"
436 * <node>
437 * time_low = 4*<hexOctet>
438 * time_mid = 2*<hexOctet>
439 * time_high_and_version = 2*<hexOctet>
440 * variant_and_sequence = 2*<hexOctet>
441 * node = 6*<hexOctet>
442 * hexOctet = <hexDigit><hexDigit>
443 * hexDigit =
444 * "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
445 * | "a" | "b" | "c" | "d" | "e" | "f"
446 * | "A" | "B" | "C" | "D" | "E" | "F"
447 * }</pre></blockquote>
448 *
449 * @return A string representation of this {@code UUID}
450 */
451 public String toString()
452 {
453 return toString(getMostSignificantBits(), getLeastSignificantBits());
454 }
455
456 /**
457 * Returns a {@code String} object representing a UUID passed in as
458 * two longs. Usually you will use {@link #toString()} instead.
459 * @param msb the most significant bytes
460 * @param lsb the least significant bytes
461 */
462 private static String toString(long msb, long lsb)
463 {
464 char[] uuidChars = new char[36];
465
466 digits(uuidChars, 0, 8, msb >> 32);
467 uuidChars[8] = '-';
468 digits(uuidChars, 9, 4, msb >> 16);
469 uuidChars[13] = '-';
470 digits(uuidChars, 14, 4, msb);
471 uuidChars[18] = '-';
472 digits(uuidChars, 19, 4, lsb >> 48);
473 uuidChars[23] = '-';
474 digits(uuidChars, 24, 12, lsb);
475
476 return JAVA_LANG_ACCESS.createStringSharedChars(uuidChars);
477 }
478
479 private static void digits(char[] dest, int offset, int digits, long val) {
480 long mask = 1L << (digits * 4);
481 JAVA_LANG_ACCESS.formatUnsignedLong(mask | (val & (mask - 1)), 4, dest, offset, digits);
482 }
483
484 /**
485 * Returns a hash code for this {@code UUID}.
486 *
487 * @return A hash code value for this {@code UUID}
488 */
489 public int hashCode() {
490 long hilo = mostSigBits ^ leastSigBits;
491 return ((int)(hilo >> 32)) ^ (int) hilo;
492 }
493
494 /**
495 * Compares this object to the specified object. The result is {@code
496 * true} if and only if the argument is not {@code null}, is a {@code UUID}
497 * object, has the same variant, and contains the same value, bit for bit,
498 * as this {@code UUID}.
499 *
500 * @param obj
501 * The object to be compared
|