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