1 46 package org.mr.core.util; 47 48 import java.security.MessageDigest ; 49 import java.security.NoSuchAlgorithmException ; 50 import java.security.SecureRandom ; 51 52 53 54 55 public final class UUID implements java.io.Serializable { 56 57 58 61 62 private static final long serialVersionUID = -4856846361193249489L; 63 64 69 70 private final long mostSigBits; 71 72 77 78 private final long leastSigBits; 79 80 83 84 private transient int version = -1; 85 86 89 90 private transient int variant = -1; 91 92 95 96 private transient volatile long timestamp = -1; 97 98 101 102 private transient int sequence = -1; 103 104 107 108 private transient long node = -1; 109 110 113 114 private transient int hashCode = -1; 115 116 120 121 private static volatile SecureRandom numberGenerator = null; 122 123 125 128 129 private UUID(byte[] data) { 130 131 long msb = 0; 132 133 long lsb = 0; 134 135 if( data.length != 16){ 136 throw new AssertionError (); 137 } 138 139 for (int i = 0; i < 8; i++) 140 141 msb = (msb << 8) | (data[i] & 0xff); 142 143 for (int i = 8; i < 16; i++) 144 145 lsb = (lsb << 8) | (data[i] & 0xff); 146 147 this.mostSigBits = msb; 148 149 this.leastSigBits = lsb; 150 151 } 152 153 154 163 164 public UUID(long mostSigBits, long leastSigBits) { 165 166 this.mostSigBits = mostSigBits; 167 168 this.leastSigBits = leastSigBits; 169 170 } 171 172 173 181 182 public static UUID randomUUID() { 183 184 SecureRandom ng = numberGenerator; 185 186 if (ng == null) { 187 188 numberGenerator = ng = new SecureRandom (); 189 190 } 191 192 193 byte[] randomBytes = new byte[16]; 194 195 ng.nextBytes(randomBytes); 196 197 randomBytes[6] &= 0x0f; 198 199 randomBytes[6] |= 0x40; 200 201 randomBytes[8] &= 0x3f; 202 203 randomBytes[8] |= 0x80; 204 205 UUID result = new UUID(randomBytes); 206 207 return new UUID(randomBytes); 208 209 } 210 211 212 219 220 public static UUID nameUUIDFromBytes(byte[] name) { 221 222 MessageDigest md; 223 224 try { 225 226 md = MessageDigest.getInstance("MD5"); 227 228 } catch (NoSuchAlgorithmException nsae) { 229 230 throw new InternalError ("MD5 not supported"); 231 232 } 233 234 byte[] md5Bytes = md.digest(name); 235 236 md5Bytes[6] &= 0x0f; 237 238 md5Bytes[6] |= 0x30; 239 240 md5Bytes[8] &= 0x3f; 241 242 md5Bytes[8] |= 0x80; 243 244 return new UUID(md5Bytes); 245 246 } 247 248 249 258 259 public static UUID fromString(String name) { 260 261 String [] components = name.split("-"); 262 263 if (components.length != 5) 264 265 throw new IllegalArgumentException ("Invalid UUID string: " + name); 266 267 for (int i = 0; i < 5; i++) 268 269 components[i] = "0x" + components[i]; 270 271 272 long mostSigBits = Long.decode(components[0]).longValue(); 273 274 mostSigBits <<= 16; 275 276 mostSigBits |= Long.decode(components[1]).longValue(); 277 278 mostSigBits <<= 16; 279 280 mostSigBits |= Long.decode(components[2]).longValue(); 281 282 283 long leastSigBits = Long.decode(components[3]).longValue(); 284 285 leastSigBits <<= 48; 286 287 leastSigBits |= Long.decode(components[4]).longValue(); 288 289 290 return new UUID(mostSigBits, leastSigBits); 291 292 } 293 294 296 297 302 303 public long getLeastSignificantBits() { 304 305 return leastSigBits; 306 307 } 308 309 310 315 316 public long getMostSignificantBits() { 317 318 return mostSigBits; 319 320 } 321 322 323 345 346 public int version() { 347 348 if (version < 0) { 349 350 352 version = (int) ((mostSigBits >> 12) & 0x0f); 353 354 } 355 356 return version; 357 358 } 359 360 361 384 385 public int variant() { 386 387 if (variant < 0) { 388 389 391 if ((leastSigBits >>> 63) == 0) { 392 393 variant = 0; 394 395 } else if ((leastSigBits >>> 62) == 2) { 396 397 variant = 2; 398 399 } else { 400 401 variant = (int) (leastSigBits >>> 61); 402 403 } 404 405 } 406 407 return variant; 408 409 } 410 411 412 437 438 public long timestamp() { 439 440 if (version() != 1) { 441 442 throw new UnsupportedOperationException ("Not a time-based UUID"); 443 444 } 445 446 long result = timestamp; 447 448 if (result < 0) { 449 450 result = (mostSigBits & 0x0000000000000FFFL) << 48; 451 452 result |= ((mostSigBits >> 16) & 0xFFFFL) << 32; 453 454 result |= mostSigBits >>> 32; 455 456 timestamp = result; 457 458 } 459 460 return result; 461 462 } 463 464 465 489 490 public int clockSequence() { 491 492 if (version() != 1) { 493 494 throw new UnsupportedOperationException ("Not a time-based UUID"); 495 496 } 497 498 if (sequence < 0) { 499 500 sequence = (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48); 501 502 } 503 504 return sequence; 505 506 } 507 508 509 535 536 public long node() { 537 538 if (version() != 1) { 539 540 throw new UnsupportedOperationException ("Not a time-based UUID"); 541 542 } 543 544 if (node < 0) { 545 546 node = leastSigBits & 0x0000FFFFFFFFFFFFL; 547 548 } 549 550 return node; 551 552 } 553 554 556 557 600 601 public String toString() { 602 603 return (digits(mostSigBits >> 32, 8) + "-" + 604 605 digits(mostSigBits >> 16, 4) + "-" + 606 607 digits(mostSigBits, 4) + "-" + 608 609 digits(leastSigBits >> 48, 4) + "-" + 610 611 digits(leastSigBits, 12)); 612 613 } 614 615 616 619 620 private static String digits(long val, int digits) { 621 622 long hi = 1L << (digits * 4); 623 624 return Long.toHexString(hi | (val & (hi - 1))).substring(1); 625 626 } 627 628 629 634 635 public int hashCode() { 636 637 if (hashCode == -1) { 638 639 hashCode = (int) ((mostSigBits >> 32) ^ 640 641 mostSigBits ^ 642 643 (leastSigBits >> 32) ^ 644 645 leastSigBits); 646 647 } 648 649 return hashCode; 650 651 } 652 653 654 668 669 public boolean equals(Object obj) { 670 671 if (!(obj instanceof UUID)) 672 673 return false; 674 675 if (((UUID) obj).variant() != this.variant()) 676 677 return false; 678 679 UUID id = (UUID) obj; 680 681 return (mostSigBits == id.mostSigBits && 682 683 leastSigBits == id.leastSigBits); 684 685 } 686 687 689 690 704 705 public int compareTo(UUID val) { 706 707 709 711 return (this.mostSigBits < val.mostSigBits ? -1 : 712 713 (this.mostSigBits > val.mostSigBits ? 1 : 714 715 (this.leastSigBits < val.leastSigBits ? -1 : 716 717 (this.leastSigBits > val.leastSigBits ? 1 : 718 719 0)))); 720 721 } 722 723 724 733 734 private void readObject(java.io.ObjectInputStream in) 735 736 throws java.io.IOException , ClassNotFoundException { 737 738 739 in.defaultReadObject(); 740 741 743 version = -1; 744 745 variant = -1; 746 747 timestamp = -1; 748 749 sequence = -1; 750 751 node = -1; 752 753 hashCode = -1; 754 755 } 756 757 } 758 759 | Popular Tags |