UUID.java 14 KB

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