* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.packagejava.util;import java.security.*;/*** A class that represents an immutable universally unique identifier (UUID).
* A UUID represents a 128-bit value.
*
*
There exist different variants of these global identifiers. The methods
* of this class are for manipulating the Leach-Salz variant, although the
* constructors allow the creation of any variant of UUID (described below).
*
*
The layout of a variant 2 (Leach-Salz) UUID is as follows:
*
* The most significant long consists of the following unsigned fields:
*
* 0xFFFFFFFF00000000 time_low
* 0x00000000FFFF0000 time_mid
* 0x000000000000F000 version
* 0x0000000000000FFF time_hi
*
* The least significant long consists of the following unsigned fields:
*
* 0xC000000000000000 variant
* 0x3FFF000000000000 clock_seq
* 0x0000FFFFFFFFFFFF node
*
*
*
The variant field contains a value which identifies the layout of the
* {@codeUUID}. The bit layout described above is valid only for a {@code* UUID} with a variant value of 2, which indicates the Leach-Salz variant.
*
*
The version field holds a value that describes the type of this {@code* UUID}. There are four different basic types of UUIDs: time-based, DCE
* security, name-based, and randomly generated UUIDs. These types have a
* version value of 1, 2, 3 and 4, respectively.
*
*
For more information including algorithms used to create {@codeUUID}s,
* see RFC 4122: A
* Universally Unique IDentifier (UUID) URN Namespace, section 4.2
* "Algorithms for Creating a Time-Based UUID".
*
*@since1.5*/
public final class UUID implements java.io.Serializable, Comparable{/*** Explicit serialVersionUID for interoperability.*/
private static final long serialVersionUID = -4856846361193249489L;/** The most significant 64 bits of this UUID.
*
* @serial*/
private final longmostSigBits;/** The least significant 64 bits of this UUID.
*
* @serial*/
private final longleastSigBits;/** The random number generator used by this class to create random
* based UUIDs. In a holder class to defer initialization until needed.*/
private static classHolder {static final SecureRandom numberGenerator = newSecureRandom();
}//Constructors and Factories
/** Private constructor which uses a byte array to construct the new UUID.*/
private UUID(byte[] data) {long msb = 0;long lsb = 0;assert data.length == 16 : "data must be 16 bytes in length";for (int i=0; i<8; i++)
msb= (msb << 8) | (data[i] & 0xff);for (int i=8; i<16; i++)
lsb= (lsb << 8) | (data[i] & 0xff);this.mostSigBits =msb;this.leastSigBits =lsb;
}/*** Constructs a new {@codeUUID} using the specified data. {@code* mostSigBits} is used for the most significant 64 bits of the {@code* UUID} and {@codeleastSigBits} becomes the least significant 64 bits of
* the {@codeUUID}.
*
*@parammostSigBits
* The most significant bits of the {@codeUUID}
*
*@paramleastSigBits
* The least significant bits of the {@codeUUID}*/
public UUID(long mostSigBits, longleastSigBits) {this.mostSigBits =mostSigBits;this.leastSigBits =leastSigBits;
}/*** Static factory to retrieve a type 4 (pseudo randomly generated) UUID.
*
* The {@codeUUID} is generated using a cryptographically strong pseudo
* random number generator.
*
*@returnA randomly generated {@codeUUID}*/
public staticUUID randomUUID() {
SecureRandom ng=Holder.numberGenerator;byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /*clear version*/randomBytes[6] |= 0x40; /*set to version 4*/randomBytes[8] &= 0x3f; /*clear variant*/randomBytes[8] |= 0x80; /*set to IETF variant*/
return newUUID(randomBytes);
}/*** Static factory to retrieve a type 3 (name based) {@codeUUID} based on
* the specified byte array.
*
*@paramname
* A byte array to be used to construct a {@codeUUID}
*
*@returnA {@codeUUID} generated from the specified array*/
public static UUID nameUUIDFromBytes(byte[] name) {
MessageDigest md;try{
md= MessageDigest.getInstance("MD5");
}catch(NoSuchAlgorithmException nsae) {throw new InternalError("MD5 not supported");
}byte[] md5Bytes =md.digest(name);
md5Bytes[6] &= 0x0f; /*clear version*/md5Bytes[6] |= 0x30; /*set to version 3*/md5Bytes[8] &= 0x3f; /*clear variant*/md5Bytes[8] |= 0x80; /*set to IETF variant*/
return newUUID(md5Bytes);
}/*** Creates a {@codeUUID} from the string standard representation as
* described in the {@link#toString} method.
*
*@paramname
* A string that specifies a {@codeUUID}
*
*@returnA {@codeUUID} with the specified value
*
*@throwsIllegalArgumentException
* If name does not conform to the string representation as
* described in {@link#toString}
**/
public staticUUID fromString(String name) {
String[] components= name.split("-");if (components.length != 5)throw new IllegalArgumentException("Invalid UUID string: "+name);for (int i=0; i<5; i++)
components[i]= "0x"+components[i];long mostSigBits = Long.decode(components[0]).longValue();
mostSigBits<<= 16;
mostSigBits|= Long.decode(components[1]).longValue();
mostSigBits<<= 16;
mostSigBits|= Long.decode(components[2]).longValue();long leastSigBits = Long.decode(components[3]).longValue();
leastSigBits<<= 48;
leastSigBits|= Long.decode(components[4]).longValue();return newUUID(mostSigBits, leastSigBits);
}//Field Accessor Methods
/*** Returns the least significant 64 bits of this UUID's 128 bit value.
*
*@returnThe least significant 64 bits of this UUID's 128 bit value*/
public longgetLeastSignificantBits() {returnleastSigBits;
}/*** Returns the most significant 64 bits of this UUID's 128 bit value.
*
*@returnThe most significant 64 bits of this UUID's 128 bit value*/
public longgetMostSignificantBits() {returnmostSigBits;
}/*** The version number associated with this {@codeUUID}. The version
* number describes how this {@codeUUID} was generated.
*
* The version number has the following meaning:
*
*
1 Time-based UUID*
2 DCE security UUID*
3 Name-based UUID*
4 Randomly generated UUID*
*
*@returnThe version number of this {@codeUUID}*/
public intversion() {//Version is bits masked by 0x000000000000F000 in MS long
return (int)((mostSigBits >> 12) & 0x0f);
}/*** The variant number associated with this {@codeUUID}. The variant
* number describes the layout of the {@codeUUID}.
*
* The variant number has the following meaning:
*
*
0 Reserved for NCS backward compatibility*
2 IETF RFC 4122* (Leach-Salz), used by this class
*
6 Reserved, Microsoft Corporation backward compatibility*
7 Reserved for future definition*
*
*@returnThe variant number of this {@codeUUID}*/
public intvariant() {//This field is composed of a varying number of bits.//0 - - Reserved for NCS backward compatibility//1 0 - The IETF aka Leach-Salz variant (used by this class)//1 1 0 Reserved, Microsoft backward compatibility//1 1 1 Reserved for future definition.
return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62)))& (leastSigBits >> 63));
}/*** The timestamp value associated with this UUID.
*
*
The 60 bit timestamp value is constructed from the time_low,
* time_mid, and time_hi fields of this {@codeUUID}. The resulting
* timestamp is measured in 100-nanosecond units since midnight,
* October 15, 1582 UTC.
*
*
The timestamp value is only meaningful in a time-based UUID, which
* has version type 1. If this {@codeUUID} is not a time-based UUID then
* this method throws UnsupportedOperationException.
*
*@throwsUnsupportedOperationException
* If this UUID is not a version 1 UUID*/
public longtimestamp() {if (version() != 1) {throw new UnsupportedOperationException("Not a time-based UUID");
}return (mostSigBits & 0x0FFFL) << 48
| ((mostSigBits >> 16) & 0x0FFFFL) << 32
| mostSigBits >>> 32;
}/*** The clock sequence value associated with this UUID.
*
*
The 14 bit clock sequence value is constructed from the clock
* sequence field of this UUID. The clock sequence field is used to
* guarantee temporal uniqueness in a time-based UUID.
*
*
The {@codeclockSequence} value is only meaningful in a time-based
* UUID, which has version type 1. If this UUID is not a time-based UUID
* then this method throws UnsupportedOperationException.
*
*@returnThe clock sequence of this {@codeUUID}
*
*@throwsUnsupportedOperationException
* If this UUID is not a version 1 UUID*/
public intclockSequence() {if (version() != 1) {throw new UnsupportedOperationException("Not a time-based UUID");
}return (int)((leastSigBits & 0x3FFF000000000000L) >>> 48);
}/*** The node value associated with this UUID.
*
*
The 48 bit node value is constructed from the node field of this
* UUID. This field is intended to hold the IEEE 802 address of the machine
* that generated this UUID to guarantee spatial uniqueness.
*
*
The node value is only meaningful in a time-based UUID, which has
* version type 1. If this UUID is not a time-based UUID then this method
* throws UnsupportedOperationException.
*
*@returnThe node value of this {@codeUUID}
*
*@throwsUnsupportedOperationException
* If this UUID is not a version 1 UUID*/
public longnode() {if (version() != 1) {throw new UnsupportedOperationException("Not a time-based UUID");
}return leastSigBits & 0x0000FFFFFFFFFFFFL;
}//Object Inherited Methods
/*** Returns a {@codeString} object representing this {@codeUUID}.
*
*
The UUID string representation is as described by this BNF:
*
* {@code* UUID = "-" "-"
* "-"
* "-"
*
* time_low = 4*
* time_mid = 2*
* time_high_and_version = 2*
* variant_and_sequence = 2*
* node = 6*
* hexOctet =
* hexDigit =
* "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
* | "a" | "b" | "c" | "d" | "e" | "f"
* | "A" | "B" | "C" | "D" | "E" | "F"
* }
*
*@returnA string representation of this {@codeUUID}*/
publicString toString() {return (digits(mostSigBits >> 32, 8) + "-" +digits(mostSigBits>> 16, 4) + "-" +digits(mostSigBits,4) + "-" +digits(leastSigBits>> 48, 4) + "-" +digits(leastSigBits,12));
}/**Returns val represented by the specified number of hex digits.*/
private static String digits(long val, intdigits) {long hi = 1L << (digits * 4);return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}/*** Returns a hash code for this {@codeUUID}.
*
*@returnA hash code value for this {@codeUUID}*/
public inthashCode() {long hilo = mostSigBits ^leastSigBits;return ((int)(hilo >> 32)) ^ (int) hilo;
}/*** Compares this object to the specified object. The result is {@code* true} if and only if the argument is not {@codenull}, is a {@codeUUID}
* object, has the same variant, and contains the same value, bit for bit,
* as this {@codeUUID}.
*
*@paramobj
* The object to be compared
*
*@return{@codetrue} if the objects are the same; {@codefalse}
* otherwise*/
public booleanequals(Object obj) {if ((null == obj) || (obj.getClass() != UUID.class))return false;
UUID id=(UUID)obj;return (mostSigBits == id.mostSigBits &&leastSigBits==id.leastSigBits);
}//Comparison Operations
/*** Compares this UUID with the specified UUID.
*
*
The first of two UUIDs is greater than the second if the most
* significant field in which the UUIDs differ is greater for the first
* UUID.
*
*@paramval
* {@codeUUID} to which this {@codeUUID} is to be compared
*
*@return-1, 0 or 1 as this {@codeUUID} is less than, equal to, or
* greater than {@codeval}
**/
public intcompareTo(UUID val) {//The ordering is intentionally set up so that the UUIDs//can simply be numerically compared as two numbers
return (this.mostSigBits < val.mostSigBits ? -1:
(this.mostSigBits > val.mostSigBits ? 1:
(this.leastSigBits < val.leastSigBits ? -1:
(this.leastSigBits > val.leastSigBits ? 1:0))));
}
}