Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 33471 invoked from network); 16 Dec 2004 17:19:44 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 16 Dec 2004 17:19:44 -0000 Received: (qmail 64182 invoked by uid 500); 16 Dec 2004 17:19:41 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 64157 invoked by uid 500); 16 Dec 2004 17:19:41 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 64118 invoked by uid 500); 16 Dec 2004 17:19:41 -0000 Received: (qmail 64109 invoked by uid 99); 16 Dec 2004 17:19:40 -0000 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from minotaur.apache.org (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Thu, 16 Dec 2004 09:17:53 -0800 Received: (qmail 9881 invoked by uid 1867); 16 Dec 2004 16:50:45 -0000 Date: 16 Dec 2004 16:50:45 -0000 Message-ID: <20041216165045.9880.qmail@minotaur.apache.org> From: rwinston@apache.org To: jakarta-commons-sandbox-cvs@apache.org Subject: cvs commit: jakarta-commons-sandbox/id/src/java/org/apache/commons/id/uuid UUID.java X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N rwinston 2004/12/16 08:50:45 Modified: id/src/java/org/apache/commons/id/uuid UUID.java Log: Remove commons-codec dependency Revision Changes Path 1.11 +436 -436 jakarta-commons-sandbox/id/src/java/org/apache/commons/id/uuid/UUID.java Index: UUID.java =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/id/src/java/org/apache/commons/id/uuid/UUID.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- UUID.java 14 Dec 2004 12:39:59 -0000 1.10 +++ UUID.java 16 Dec 2004 16:50:45 -0000 1.11 @@ -20,10 +20,10 @@ import java.io.Serializable; import java.util.StringTokenizer; +import org.apache.commons.id.DecoderException; import org.apache.commons.id.IdentifierUtils; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.id.uuid.utils.DigestUtils; +import org.apache.commons.id.uuid.utils.Hex; /** @@ -39,439 +39,439 @@ */ public class UUID implements Constants, Serializable, Comparable { - - /** byte array to store 128-bits composing this UUID */ - private byte[] rawBytes = new byte[UUID_BYTE_LENGTH]; - - /** Holds node identifier for this UUID */ - private Long node = null; - - /** Holds timestamp for this UUID */ - private long timestamp = -1; - - /** Holds the clock sequence field */ - private Short clockSq = null; - - /** Holds the version field of this UUID */ - private int version = -1; - - /** Holds the variant field of this UUID */ - private int variant = -1; - - /** Holds the internal string value of the UUID */ - private String stringValue = null; - - - /** Constructs a nil UUID */ - public UUID() { - super(); - } - - /** - *

Constructs a UUID from a 128 bit java.math.BigInteger.

- *

Method is protected as their is no standard as to the internal representation of a UUID. - * In this case a BigInteger is used with signum always positive.

- * - * @param bigIntValue the 128 bit BigInteger to construct this UUID from. - * @throws IllegalArgumentException argument must be 128 bit - */ - /* protected UUID(BigInteger bigIntValue) throws IllegalArgumentException { - super(); - if (bigIntValue.bitLength() > UUID.UUID_BIT_LENGTH) { - throw new IllegalArgumentException("UUID must be contructed using a 128 bit BigInteger"); - } - numberValue = bigIntValue; - } */ - - /** - *

Copy constructor.

- * - * @param copyFrom the UUID to copy to create this UUID. - */ - public UUID(UUID copyFrom) { - super(); - rawBytes = copyFrom.getRawBytes(); - } - - /** - *

Constructs a UUID from a 16 byte array.

- * - * @param byteArray the 16 byte array to construct this UUID from. - * @throws IllegalArgumentException argument must be 16 bytes - */ - public UUID(byte[] byteArray) throws IllegalArgumentException { - super(); - if (byteArray.length != UUID_BYTE_LENGTH) { - throw new IllegalArgumentException("UUID must be contructed using a 16 byte array."); - } - // UUID must be immutable so a copy is used. - System.arraycopy(byteArray, 0, rawBytes, 0, UUID_BYTE_LENGTH); - } - - /** - *

Constructs a UUID from a DataInput. Note if 16 bytes are not available this method will block.

- * - * @param input the datainput with 16 bytes to read in from. - * @throws IOException exception if there is an IO problem also argument must contain 16 bytes. - */ - public UUID(DataInput input) throws IOException { - super(); - input.readFully(rawBytes, 0, UUID_BYTE_LENGTH); - } - - /** - *

Constructs a UUID from two long values in most significant byte, and least significant bytes order.

- * - * @param mostSignificant - the most significant 8 bytes of the uuid to be constructed. - * @param leastSignificant - the least significant 8 bytes of the uuid to be constructed. - */ - public UUID(long mostSignificant, long leastSignificant) { - rawBytes = Bytes.append(Bytes.toBytes(mostSignificant), Bytes.toBytes(leastSignificant)); - } - - /** - *

Constructs a UUID from a UUID formatted String.

- * - * @param uuidString the String representing a UUID to construct this UUID - * @throws UUIDFormatException String must be a properly formatted UUID string - */ - public UUID(String uuidString) throws UUIDFormatException { - //Calls the copy constructor - this(UUID.fromString(uuidString)); - } - - /** - *

Parses a string for a UUID.

- * - * @param uuidString the UUID formatted String to parse. - * @throws UUIDFormatException the String must be a properly formatted UUID String. - * @return Returns a UUID or null if the formatted string could not be parsed. - */ - public static UUID fromString(String uuidString) - throws UUIDFormatException { - String leanString = uuidString.toLowerCase(); - UUID tmpUUID = null; - - //Handle prefixed UUIDs - // e.g. urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 - int pos = uuidString.lastIndexOf(":"); - if (pos > 1) { - leanString = uuidString.substring(++pos, uuidString.length()); - } - - //Check for 36 char length - if (leanString.length() != UUID_FORMATTED_LENGTH) { - throw new UUIDFormatException(); - } - - //Check for 5 fields - StringTokenizer tok = new StringTokenizer(leanString, "-"); - if ( tok.countTokens() != TOKENS_IN_UUID ) { - throw new UUIDFormatException(); - } - - //Remove the "-" from the formatted string and test token sizes - StringBuffer buf = new StringBuffer(UUID_UNFORMATTED_LENGTH); - String token = null; - int count = 0; - while (tok.hasMoreTokens()) { - token = tok.nextToken(); - if (token.length() != TOKEN_LENGTHS[count++]) { - throw new UUIDFormatException(); - } - buf.append(token); - } - - //Create from the hex value - try { - char[] chars = buf.toString().toCharArray(); - tmpUUID = new UUID(Hex.decodeHex(chars)); - } catch (DecoderException de) { - throw new UUIDFormatException(de.getMessage()); - } - return tmpUUID; - } - - /** - *

Returns a string representation of the UUID.

- * - * @return a string representation of the UUID formatted according to the specification. - */ - public String toString() { - //set string value if not set - if (stringValue == null) { - StringBuffer buf = new StringBuffer(new String(Hex.encodeHex(rawBytes))); - while (buf.length() != UUID_UNFORMATTED_LENGTH) { - buf.insert(0, "0"); - } - buf.ensureCapacity(UUID_FORMATTED_LENGTH); - buf.insert(FORMAT_POSITION1, '-'); - buf.insert(FORMAT_POSITION2, '-'); - buf.insert(FORMAT_POSITION3, '-'); - buf.insert(FORMAT_POSITION4, '-'); - stringValue = buf.toString(); - } - return stringValue; - } - - /** - *

Returns a urn representation of the UUID. This is same as the - * toString() value prefixed with urn:uuid:

- * - * @return Returns the urn string representation of the UUID - */ - public String toUrn() { - return URN_PREFIX + this.toString(); - } - - /** - *

Compares two UUID for equality.

- * - * @see java.lang.Object#equals(Object) - */ - - public boolean equals(Object obj) { - if (!(obj instanceof UUID)) { - return false; - } - return Bytes.areEqual( ((UUID) obj).getRawBytes(), rawBytes); - } - - /** - *

Returns a hash code value for the object.

- * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - int iConstant = 37; - int iTotal = 17; - for (int i = 0; i < rawBytes.length; i++) { - iTotal = iTotal * iConstant + rawBytes[i]; - } - return iTotal; - } - - /** - *

Compares two UUID's for equality

- * - * @see Comparable#compareTo(Object) - */ - public int compareTo(Object compareTo) throws ClassCastException { - if (!(compareTo instanceof UUID)) { - throw new ClassCastException(); - } - return (Bytes.compareTo(rawBytes, ((UUID) compareTo).getRawBytes())); - } - - /** - *

Returns the clock sequence value in the UUID. The clock sequence is a random assigned to a particular clock instance that - * generated the time in the timestamp of a time based UUID.

- * - * @return the clock sequence value in the UUID. - * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. - */ - public int clockSequence() throws UnsupportedOperationException { - //if variant is not mealling leach salz throw unsupported operation exception - if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { - throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); - } - if (clockSq == null) { - byte[] b = {((byte) (rawBytes[8] & 0x3F)), rawBytes[9]}; - clockSq = new Short(Bytes.toShort(b)); - } - return clockSq.intValue(); - } - - /** - *

Returns the version of the UUID. - *

    - *
  • VERSION_ONE - The time-based version
  • - *
  • VERSION_TWO - DCE Security version, with embedded POSIX UIDs.
  • - *
  • VERSION_THREE - Name based UUID with MD5 hashing.
  • - *
  • VERSION_FOUR - Random based UUID.
  • - *
  • VERSION_FIVE - Name based UUID with SHA-1 hashing.
  • - *
- *

- * @return the version of the UUID. - */ - public int version() { - if (version == -1) { - version = ((rawBytes[6] >>> 4) & 0x0F); - } - return version; - } - - /** - *

Returns the variant field of the UUID.

- * - * @return Returns the variant field of the UUID. - * @see UUID#VARIANT_NCS_COMPAT - * @see UUID#VARIANT_IETF_DRAFT - * @see UUID#VARIANT_MS - * @see UUID#VARIANT_FUTURE - */ - public int variant() { - if (variant == -1) { - if ((rawBytes[8] & 0x80) == 0x0) { - variant = VARIANT_NCS_COMPAT; - } else if ((rawBytes[8] & 0x40) == 0x0) { - variant = VARIANT_IETF_DRAFT; - } else if ((rawBytes[8] & 0x20) == 0x0) { - variant = VARIANT_MS; - } else { - variant = VARIANT_FUTURE; - } - } - return variant; - } - - /** - *

Returns the node identifier found in this UUID. The specification was written such that this value holds the IEEE 802 MAC - * address. The specification permits this value to be calculated from other sources other than the MAC.

- * - * @return the node identifier found in this UUID. - * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. - */ - public long node() throws UnsupportedOperationException { - //if variant is not mealling leach salz throw unsupported operation exception - if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { - throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); - } - if (node == null) { - byte[] b = new byte[8]; - System.arraycopy(rawBytes, 10, b, 2, 6); - node = new Long((Bytes.toLong(b) & 0xFFFFFFFFFFFFL)); - } - return node.longValue(); - } - - /** - *

Returns the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset (00:00:00.00, 15 - * October 1582 ).

- * - * @return the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset. - * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. - */ - public long timestamp() throws UnsupportedOperationException { - //if variant is not mealling leach salz throw unsupported operation exception - if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { - throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); - } - if (timestamp == -1) { - byte[] longVal = new byte[8]; - System.arraycopy(rawBytes, TIME_HI_START_POS, longVal, TIME_HI_TS_POS, TIME_HI_BYTE_LEN); - System.arraycopy(rawBytes, TIME_MID_START_POS, longVal, TIME_MID_TS_POS, TIME_MID_BYTE_LEN); - System.arraycopy(rawBytes, TIME_LOW_START_POS, longVal, TIME_LOW_TS_POS, TIME_LOW_BYTE_LEN); - longVal[TIME_HI_TS_POS] &= 0x0F; - timestamp = Bytes.toLong(longVal); - } - return timestamp; - } - - /** - *

Returns the least significant bits stored in the uuid's internal structure.

- * - * @return the least significant bits stored in the uuid's internal structure. - */ - long getLeastSignificantBits() { - byte[] lsb = new byte[8]; - System.arraycopy(rawBytes, 8, lsb, 0, 8); - return Bytes.toLong(lsb); - } - - /** - *

Returns the least significant bits stored in the uuid's internal structure.

- * - * @return the least significant bits stored in the uuid's internal structure. - */ - long getMostSignificantBits() { - byte[] msb = new byte[8]; - System.arraycopy(rawBytes, 0, msb, 0, 8); - return Bytes.toLong(msb); - } - - /** - *

Returns a copy of the byte values contained in this UUID. - * - * @return a copy of the byte values contained in this UUID. - */ - public byte[] getRawBytes() { - byte[] ret = new byte[UUID_BYTE_LENGTH]; - System.arraycopy(rawBytes, 0, ret, 0, UUID_BYTE_LENGTH); - return ret; - } - - /** - *

Returns a new version 4 UUID, based upon Random bits.

- * - * @return a new version 4 UUID, based upon Random bits. - */ - static UUID randomUUID() { - return (UUID) IdentifierUtils.UUID_VERSION_FOUR_GENERATOR.nextIdentifier(); - } - - /** - *

Returns a new version 1 UUID, based upon node identifier and time stamp.

- * - * @return a new version 1 UUID, based upon node identifier and time stamp. - */ - static UUID timeUUID() { - return (UUID) IdentifierUtils.UUID_VERSION_ONE_GENERATOR.nextIdentifier(); - } - - /** - *

Returns a new version three (MD5) or five (SHA-1) UUID, using the specified encoding - * given a name and the namespace's UUID.

- * - * @param name String the name to calculate the UUID for. - * @param namespace UUID assigned to this namespace. - * @param encoding The encoding to use, either #{link UUID.MD5_ENCODING} or #{link UUID.SHA1_ENCODING} - * @return a new version three UUID given a name and the namespace's UUID. - */ - static UUID nameUUIDFromString(String name, UUID namespace, String encoding) { - byte[] nameAsBytes = name.getBytes(); - byte[] concat = new byte[UUID_BYTE_LENGTH + nameAsBytes.length]; - System.arraycopy(namespace.getRawBytes(), 0, concat, 0, UUID_BYTE_LENGTH); - System.arraycopy(nameAsBytes, 0, concat, UUID_BYTE_LENGTH, nameAsBytes.length); - - byte[] raw = null; - - if(encoding.equals(UUID.MD5_ENCODING)) { - raw = DigestUtils.md5(concat); - } - else if(encoding.equals(UUID.SHA1_ENCODING)) { - byte[] shaDigest = DigestUtils.sha(concat); - // Truncate digest to 16 bytes (SHA-1 returns a 20-byte digest) - raw = new byte[16]; - System.arraycopy(shaDigest, 0, raw, 0, 16); - } - else { - throw new RuntimeException("Unsupported encoding " + encoding); + + /** byte array to store 128-bits composing this UUID */ + private byte[] rawBytes = new byte[UUID_BYTE_LENGTH]; + + /** Holds node identifier for this UUID */ + private Long node = null; + + /** Holds timestamp for this UUID */ + private long timestamp = -1; + + /** Holds the clock sequence field */ + private Short clockSq = null; + + /** Holds the version field of this UUID */ + private int version = -1; + + /** Holds the variant field of this UUID */ + private int variant = -1; + + /** Holds the internal string value of the UUID */ + private String stringValue = null; + + + /** Constructs a nil UUID */ + public UUID() { + super(); } + /** + *

Constructs a UUID from a 128 bit java.math.BigInteger.

+ *

Method is protected as their is no standard as to the internal representation of a UUID. + * In this case a BigInteger is used with signum always positive.

+ * + * @param bigIntValue the 128 bit BigInteger to construct this UUID from. + * @throws IllegalArgumentException argument must be 128 bit + */ + /* protected UUID(BigInteger bigIntValue) throws IllegalArgumentException { + super(); + if (bigIntValue.bitLength() > UUID.UUID_BIT_LENGTH) { + throw new IllegalArgumentException("UUID must be contructed using a 128 bit BigInteger"); + } + numberValue = bigIntValue; + } */ + + /** + *

Copy constructor.

+ * + * @param copyFrom the UUID to copy to create this UUID. + */ + public UUID(UUID copyFrom) { + super(); + rawBytes = copyFrom.getRawBytes(); + } + + /** + *

Constructs a UUID from a 16 byte array.

+ * + * @param byteArray the 16 byte array to construct this UUID from. + * @throws IllegalArgumentException argument must be 16 bytes + */ + public UUID(byte[] byteArray) throws IllegalArgumentException { + super(); + if (byteArray.length != UUID_BYTE_LENGTH) { + throw new IllegalArgumentException("UUID must be contructed using a 16 byte array."); + } + // UUID must be immutable so a copy is used. + System.arraycopy(byteArray, 0, rawBytes, 0, UUID_BYTE_LENGTH); + } + + /** + *

Constructs a UUID from a DataInput. Note if 16 bytes are not available this method will block.

+ * + * @param input the datainput with 16 bytes to read in from. + * @throws IOException exception if there is an IO problem also argument must contain 16 bytes. + */ + public UUID(DataInput input) throws IOException { + super(); + input.readFully(rawBytes, 0, UUID_BYTE_LENGTH); + } + + /** + *

Constructs a UUID from two long values in most significant byte, and least significant bytes order.

+ * + * @param mostSignificant - the most significant 8 bytes of the uuid to be constructed. + * @param leastSignificant - the least significant 8 bytes of the uuid to be constructed. + */ + public UUID(long mostSignificant, long leastSignificant) { + rawBytes = Bytes.append(Bytes.toBytes(mostSignificant), Bytes.toBytes(leastSignificant)); + } + + /** + *

Constructs a UUID from a UUID formatted String.

+ * + * @param uuidString the String representing a UUID to construct this UUID + * @throws UUIDFormatException String must be a properly formatted UUID string + */ + public UUID(String uuidString) throws UUIDFormatException { + //Calls the copy constructor + this(UUID.fromString(uuidString)); + } + + /** + *

Parses a string for a UUID.

+ * + * @param uuidString the UUID formatted String to parse. + * @throws UUIDFormatException the String must be a properly formatted UUID String. + * @return Returns a UUID or null if the formatted string could not be parsed. + */ + public static UUID fromString(String uuidString) + throws UUIDFormatException { + String leanString = uuidString.toLowerCase(); + UUID tmpUUID = null; + + //Handle prefixed UUIDs + // e.g. urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + int pos = uuidString.lastIndexOf(":"); + if (pos > 1) { + leanString = uuidString.substring(++pos, uuidString.length()); + } + + //Check for 36 char length + if (leanString.length() != UUID_FORMATTED_LENGTH) { + throw new UUIDFormatException(); + } + + //Check for 5 fields + StringTokenizer tok = new StringTokenizer(leanString, "-"); + if ( tok.countTokens() != TOKENS_IN_UUID ) { + throw new UUIDFormatException(); + } + + //Remove the "-" from the formatted string and test token sizes + StringBuffer buf = new StringBuffer(UUID_UNFORMATTED_LENGTH); + String token = null; + int count = 0; + while (tok.hasMoreTokens()) { + token = tok.nextToken(); + if (token.length() != TOKEN_LENGTHS[count++]) { + throw new UUIDFormatException(); + } + buf.append(token); + } + + //Create from the hex value + try { + char[] chars = buf.toString().toCharArray(); + tmpUUID = new UUID(Hex.decodeHex(chars)); + } catch (DecoderException de) { + throw new UUIDFormatException(de.getMessage()); + } + return tmpUUID; + } + + /** + *

Returns a string representation of the UUID.

+ * + * @return a string representation of the UUID formatted according to the specification. + */ + public String toString() { + //set string value if not set + if (stringValue == null) { + StringBuffer buf = new StringBuffer(new String(Hex.encodeHex(rawBytes))); + while (buf.length() != UUID_UNFORMATTED_LENGTH) { + buf.insert(0, "0"); + } + buf.ensureCapacity(UUID_FORMATTED_LENGTH); + buf.insert(FORMAT_POSITION1, '-'); + buf.insert(FORMAT_POSITION2, '-'); + buf.insert(FORMAT_POSITION3, '-'); + buf.insert(FORMAT_POSITION4, '-'); + stringValue = buf.toString(); + } + return stringValue; + } + + /** + *

Returns a urn representation of the UUID. This is same as the + * toString() value prefixed with urn:uuid:

+ * + * @return Returns the urn string representation of the UUID + */ + public String toUrn() { + return URN_PREFIX + this.toString(); + } + + /** + *

Compares two UUID for equality.

+ * + * @see java.lang.Object#equals(Object) + */ + + public boolean equals(Object obj) { + if (!(obj instanceof UUID)) { + return false; + } + return Bytes.areEqual( ((UUID) obj).getRawBytes(), rawBytes); + } + + /** + *

Returns a hash code value for the object.

+ * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + int iConstant = 37; + int iTotal = 17; + for (int i = 0; i < rawBytes.length; i++) { + iTotal = iTotal * iConstant + rawBytes[i]; + } + return iTotal; + } + + /** + *

Compares two UUID's for equality

+ * + * @see Comparable#compareTo(Object) + */ + public int compareTo(Object compareTo) throws ClassCastException { + if (!(compareTo instanceof UUID)) { + throw new ClassCastException(); + } + return (Bytes.compareTo(rawBytes, ((UUID) compareTo).getRawBytes())); + } + + /** + *

Returns the clock sequence value in the UUID. The clock sequence is a random assigned to a particular clock instance that + * generated the time in the timestamp of a time based UUID.

+ * + * @return the clock sequence value in the UUID. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public int clockSequence() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (clockSq == null) { + byte[] b = {((byte) (rawBytes[8] & 0x3F)), rawBytes[9]}; + clockSq = new Short(Bytes.toShort(b)); + } + return clockSq.intValue(); + } + + /** + *

Returns the version of the UUID. + *

    + *
  • VERSION_ONE - The time-based version
  • + *
  • VERSION_TWO - DCE Security version, with embedded POSIX UIDs.
  • + *
  • VERSION_THREE - Name based UUID with MD5 hashing.
  • + *
  • VERSION_FOUR - Random based UUID.
  • + *
  • VERSION_FIVE - Name based UUID with SHA-1 hashing.
  • + *
+ *

+ * @return the version of the UUID. + */ + public int version() { + if (version == -1) { + version = ((rawBytes[6] >>> 4) & 0x0F); + } + return version; + } + + /** + *

Returns the variant field of the UUID.

+ * + * @return Returns the variant field of the UUID. + * @see UUID#VARIANT_NCS_COMPAT + * @see UUID#VARIANT_IETF_DRAFT + * @see UUID#VARIANT_MS + * @see UUID#VARIANT_FUTURE + */ + public int variant() { + if (variant == -1) { + if ((rawBytes[8] & 0x80) == 0x0) { + variant = VARIANT_NCS_COMPAT; + } else if ((rawBytes[8] & 0x40) == 0x0) { + variant = VARIANT_IETF_DRAFT; + } else if ((rawBytes[8] & 0x20) == 0x0) { + variant = VARIANT_MS; + } else { + variant = VARIANT_FUTURE; + } + } + return variant; + } + + /** + *

Returns the node identifier found in this UUID. The specification was written such that this value holds the IEEE 802 MAC + * address. The specification permits this value to be calculated from other sources other than the MAC.

+ * + * @return the node identifier found in this UUID. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public long node() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (node == null) { + byte[] b = new byte[8]; + System.arraycopy(rawBytes, 10, b, 2, 6); + node = new Long((Bytes.toLong(b) & 0xFFFFFFFFFFFFL)); + } + return node.longValue(); + } + + /** + *

Returns the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset (00:00:00.00, 15 + * October 1582 ).

+ * + * @return the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public long timestamp() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (timestamp == -1) { + byte[] longVal = new byte[8]; + System.arraycopy(rawBytes, TIME_HI_START_POS, longVal, TIME_HI_TS_POS, TIME_HI_BYTE_LEN); + System.arraycopy(rawBytes, TIME_MID_START_POS, longVal, TIME_MID_TS_POS, TIME_MID_BYTE_LEN); + System.arraycopy(rawBytes, TIME_LOW_START_POS, longVal, TIME_LOW_TS_POS, TIME_LOW_BYTE_LEN); + longVal[TIME_HI_TS_POS] &= 0x0F; + timestamp = Bytes.toLong(longVal); + } + return timestamp; + } + + /** + *

Returns the least significant bits stored in the uuid's internal structure.

+ * + * @return the least significant bits stored in the uuid's internal structure. + */ + long getLeastSignificantBits() { + byte[] lsb = new byte[8]; + System.arraycopy(rawBytes, 8, lsb, 0, 8); + return Bytes.toLong(lsb); + } + + /** + *

Returns the least significant bits stored in the uuid's internal structure.

+ * + * @return the least significant bits stored in the uuid's internal structure. + */ + long getMostSignificantBits() { + byte[] msb = new byte[8]; + System.arraycopy(rawBytes, 0, msb, 0, 8); + return Bytes.toLong(msb); + } + + /** + *

Returns a copy of the byte values contained in this UUID. + * + * @return a copy of the byte values contained in this UUID. + */ + public byte[] getRawBytes() { + byte[] ret = new byte[UUID_BYTE_LENGTH]; + System.arraycopy(rawBytes, 0, ret, 0, UUID_BYTE_LENGTH); + return ret; + } + + /** + *

Returns a new version 4 UUID, based upon Random bits.

+ * + * @return a new version 4 UUID, based upon Random bits. + */ + public static UUID randomUUID() { + return (UUID) IdentifierUtils.UUID_VERSION_FOUR_GENERATOR.nextIdentifier(); + } + + /** + *

Returns a new version 1 UUID, based upon node identifier and time stamp.

+ * + * @return a new version 1 UUID, based upon node identifier and time stamp. + */ + public static UUID timeUUID() { + return (UUID) IdentifierUtils.UUID_VERSION_ONE_GENERATOR.nextIdentifier(); + } + + /** + *

Returns a new version three (MD5) or five (SHA-1) UUID, using the specified encoding + * given a name and the namespace's UUID.

+ * + * @param name String the name to calculate the UUID for. + * @param namespace UUID assigned to this namespace. + * @param encoding The encoding to use, either #{link UUID.MD5_ENCODING} or #{link UUID.SHA1_ENCODING} + * @return a new version three UUID given a name and the namespace's UUID. + */ + public static UUID nameUUIDFromString(String name, UUID namespace, String encoding) { + byte[] nameAsBytes = name.getBytes(); + byte[] concat = new byte[UUID_BYTE_LENGTH + nameAsBytes.length]; + System.arraycopy(namespace.getRawBytes(), 0, concat, 0, UUID_BYTE_LENGTH); + System.arraycopy(nameAsBytes, 0, concat, UUID_BYTE_LENGTH, nameAsBytes.length); + + byte[] raw = null; + + if(encoding.equals(UUID.MD5_ENCODING)) { + raw = DigestUtils.md5(concat); + } + else if(encoding.equals(UUID.SHA1_ENCODING)) { + byte[] shaDigest = DigestUtils.sha(concat); + // Truncate digest to 16 bytes (SHA-1 returns a 20-byte digest) + raw = new byte[16]; + System.arraycopy(shaDigest, 0, raw, 0, 16); + } + else { + throw new RuntimeException("Unsupported encoding " + encoding); + } + + + //Set version (version 3 and version 5 are identical on a bit-level, + //thus we only need ever set one of them + raw[TIME_HI_AND_VERSION_BYTE_6] &= 0x0F; + raw[TIME_HI_AND_VERSION_BYTE_6] |= (UUID.VERSION_THREE << 4); + + //Set variant + raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] &= 0x3F; //0011 1111 + raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] |= 0x80; //1000 0000 + + return new UUID(raw); + } + + /** + *

Returns a new version three UUID given a name and the namespace's UUID.

+ * + * @param name String the name to calculate the UUID for. + * @param namespace UUID assigned to this namespace. + * @return a new version three UUID given a name and the namespace's UUID. + * + */ + public static UUID nameUUIDFromString(String name, UUID namespace) { + return nameUUIDFromString(name, namespace, UUID.MD5_ENCODING); + } - //Set version (version 3 and version 5 are identical on a bit-level, - //thus we only need ever set one of them - raw[TIME_HI_AND_VERSION_BYTE_6] &= 0x0F; - raw[TIME_HI_AND_VERSION_BYTE_6] |= (UUID.VERSION_THREE << 4); - - //Set variant - raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] &= 0x3F; //0011 1111 - raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] |= 0x80; //1000 0000 - - return new UUID(raw); - } - - /** - *

Returns a new version three UUID given a name and the namespace's UUID.

- * - * @param name String the name to calculate the UUID for. - * @param namespace UUID assigned to this namespace. - * @return a new version three UUID given a name and the namespace's UUID. - * - */ - static UUID nameUUIDFromString(String name, UUID namespace) { - return nameUUIDFromString(name, namespace, UUID.MD5_ENCODING); - } - } --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org