1 7 8 package java.util; 9 10 import java.security.*; 11 import java.io.IOException ; 12 import java.io.UnsupportedEncodingException ; 13 14 57 public final class UUID 58 implements java.io.Serializable , Comparable <UUID > { 59 60 63 private static final long serialVersionUID = -4856846361193249489L; 64 65 70 private final long mostSigBits; 71 72 77 private final long leastSigBits; 78 79 82 private transient int version = -1; 83 84 87 private transient int variant = -1; 88 89 92 private transient volatile long timestamp = -1; 93 94 97 private transient int sequence = -1; 98 99 102 private transient long node = -1; 103 104 107 private transient int hashCode = -1; 108 109 113 private static volatile SecureRandom numberGenerator = null; 114 115 117 120 private UUID(byte[] data) { 121 long msb = 0; 122 long lsb = 0; 123 assert data.length == 16; 124 for (int i=0; i<8; i++) 125 msb = (msb << 8) | (data[i] & 0xff); 126 for (int i=8; i<16; i++) 127 lsb = (lsb << 8) | (data[i] & 0xff); 128 this.mostSigBits = msb; 129 this.leastSigBits = lsb; 130 } 131 132 141 public UUID(long mostSigBits, long leastSigBits) { 142 this.mostSigBits = mostSigBits; 143 this.leastSigBits = leastSigBits; 144 } 145 146 154 public static UUID randomUUID() { 155 SecureRandom ng = numberGenerator; 156 if (ng == null) { 157 numberGenerator = ng = new SecureRandom(); 158 } 159 160 byte[] randomBytes = new byte[16]; 161 ng.nextBytes(randomBytes); 162 randomBytes[6] &= 0x0f; 163 randomBytes[6] |= 0x40; 164 randomBytes[8] &= 0x3f; 165 randomBytes[8] |= 0x80; 166 UUID result = new UUID (randomBytes); 167 return new UUID (randomBytes); 168 } 169 170 177 public static UUID nameUUIDFromBytes(byte[] name) { 178 MessageDigest md; 179 try { 180 md = MessageDigest.getInstance("MD5"); 181 } catch (NoSuchAlgorithmException nsae) { 182 throw new InternalError ("MD5 not supported"); 183 } 184 byte[] md5Bytes = md.digest(name); 185 md5Bytes[6] &= 0x0f; 186 md5Bytes[6] |= 0x30; 187 md5Bytes[8] &= 0x3f; 188 md5Bytes[8] |= 0x80; 189 return new UUID (md5Bytes); 190 } 191 192 201 public static UUID fromString(String name) { 202 String [] components = name.split("-"); 203 if (components.length != 5) 204 throw new IllegalArgumentException ("Invalid UUID string: "+name); 205 for (int i=0; i<5; i++) 206 components[i] = "0x"+components[i]; 207 208 long mostSigBits = Long.decode(components[0]).longValue(); 209 mostSigBits <<= 16; 210 mostSigBits |= Long.decode(components[1]).longValue(); 211 mostSigBits <<= 16; 212 mostSigBits |= Long.decode(components[2]).longValue(); 213 214 long leastSigBits = Long.decode(components[3]).longValue(); 215 leastSigBits <<= 48; 216 leastSigBits |= Long.decode(components[4]).longValue(); 217 218 return new UUID (mostSigBits, leastSigBits); 219 } 220 221 223 228 public long getLeastSignificantBits() { 229 return leastSigBits; 230 } 231 232 237 public long getMostSignificantBits() { 238 return mostSigBits; 239 } 240 241 255 public int version() { 256 if (version < 0) { 257 version = (int)((mostSigBits >> 12) & 0x0f); 259 } 260 return version; 261 } 262 263 277 public int variant() { 278 if (variant < 0) { 279 if ((leastSigBits >>> 63) == 0) { 281 variant = 0; 282 } else if ((leastSigBits >>> 62) == 2) { 283 variant = 2; 284 } else { 285 variant = (int)(leastSigBits >>> 61); 286 } 287 } 288 return variant; 289 } 290 291 306 public long timestamp() { 307 if (version() != 1) { 308 throw new UnsupportedOperationException ("Not a time-based UUID"); 309 } 310 long result = timestamp; 311 if (result < 0) { 312 result = (mostSigBits & 0x0000000000000FFFL) << 48; 313 result |= ((mostSigBits >> 16) & 0xFFFFL) << 32; 314 result |= mostSigBits >>> 32; 315 timestamp = result; 316 } 317 return result; 318 } 319 320 335 public int clockSequence() { 336 if (version() != 1) { 337 throw new UnsupportedOperationException ("Not a time-based UUID"); 338 } 339 if (sequence < 0) { 340 sequence = (int)((leastSigBits & 0x3FFF000000000000L) >>> 48); 341 } 342 return sequence; 343 } 344 345 361 public long node() { 362 if (version() != 1) { 363 throw new UnsupportedOperationException ("Not a time-based UUID"); 364 } 365 if (node < 0) { 366 node = leastSigBits & 0x0000FFFFFFFFFFFFL; 367 } 368 return node; 369 } 370 371 373 397 public String toString() { 398 return (digits(mostSigBits >> 32, 8) + "-" + 399 digits(mostSigBits >> 16, 4) + "-" + 400 digits(mostSigBits, 4) + "-" + 401 digits(leastSigBits >> 48, 4) + "-" + 402 digits(leastSigBits, 12)); 403 } 404 405 406 private static String digits(long val, int digits) { 407 long hi = 1L << (digits * 4); 408 return Long.toHexString(hi | (val & (hi - 1))).substring(1); 409 } 410 411 416 public int hashCode() { 417 if (hashCode == -1) { 418 hashCode = (int)((mostSigBits >> 32) ^ 419 mostSigBits ^ 420 (leastSigBits >> 32) ^ 421 leastSigBits); 422 } 423 return hashCode; 424 } 425 426 436 public boolean equals(Object obj) { 437 if (!(obj instanceof UUID )) 438 return false; 439 if (((UUID )obj).variant() != this.variant()) 440 return false; 441 UUID id = (UUID )obj; 442 return (mostSigBits == id.mostSigBits && 443 leastSigBits == id.leastSigBits); 444 } 445 446 448 458 public int compareTo(UUID val) { 459 return (this.mostSigBits < val.mostSigBits ? -1 : 462 (this.mostSigBits > val.mostSigBits ? 1 : 463 (this.leastSigBits < val.leastSigBits ? -1 : 464 (this.leastSigBits > val.leastSigBits ? 1 : 465 0)))); 466 } 467 468 474 private void readObject(java.io.ObjectInputStream in) 475 throws java.io.IOException , ClassNotFoundException { 476 477 in.defaultReadObject(); 478 479 version = -1; 481 variant = -1; 482 timestamp = -1; 483 sequence = -1; 484 node = -1; 485 hashCode = -1; 486 } 487 } 488 | Popular Tags |