1 | package org.columba.calendar.base;↵ | | 1 | package org.columba.core.base;↵
|
|
2 | import java.security.SecureRandom;↵ | | 2 | import java.security.SecureRandom;↵
|
|
3 | /**↵ | | 3 | /**↵
|
4 | * A universally unique identifier (UUID). A UUID is a 128-bit value.↵ | | 4 | * A universally unique identifier (UUID). A UUID is a 128-bit value.↵
|
5 | * <p>↵ | | 5 | * <p>↵
|
6 | * Standard RFC:↵ | | 6 | * Standard RFC 4122:↵
|
7 | * http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-05.txt↵ | | 7 | * ftp://ftp.isi.edu/in-notes/rfc4122.txt↵
|
8 | * <p>↵ | | 8 | * <p>↵
|
9 | */↵ | | 9 | */↵
|
10 | public class UUIDGenerator {↵ | | 10 | public class UUIDGenerator {↵
|
|
11 | /**↵ | | 11 | /**↵
|
12 | * random number generator for UUID generation↵ | | 12 | * random number generator for UUID generation↵
|
13 | */↵ | | 13 | */↵
|
14 | private final SecureRandom secRand = new SecureRandom();↵ | | 14 | private final SecureRandom secRand = new SecureRandom();↵
|
|
15 | /**↵ | | 15 | /**↵
|
16 | * 128-bit buffer for use with secRand↵ | | 16 | * 128-bit buffer for use with secRand↵
|
17 | */↵ | | 17 | */↵
|
18 | private final byte[] secRandBuf16 = new byte[16];↵ | | 18 | private final byte[] secRandBuf16 = new byte[16];↵
|
|
19 | public UUIDGenerator() {↵ | | 19 | public UUIDGenerator() {↵
|
20 | super();↵ | | 20 | super();↵
|
21 | }↵ | | 21 | }↵
|
|
22 | /**↵ | | 22 | /**↵
|
23 | * @return uuid as String↵ | | 23 | * @return uuid as String↵
|
24 | */↵ | | 24 | */↵
|
25 | public String newUUID() {↵ | | 25 | public String newUUID() {↵
|
26 | secRand.nextBytes(secRandBuf16);↵ | | 26 | secRand.nextBytes(secRandBuf16);↵
|
27 | secRandBuf16[6] &= 0x0f;↵ | | 27 | secRandBuf16[6] &= 0x0f;↵
|
28 | secRandBuf16[6] |= 0x40; /* version 4 */↵ | | 28 | secRandBuf16[6] |= 0x40; /* version 4 */↵
|
29 | secRandBuf16[8] &= 0x3f;↵ | | 29 | secRandBuf16[8] &= 0x3f;↵
|
30 | secRandBuf16[8] |= 0x80; /* IETF variant */↵ | | 30 | secRandBuf16[8] |= 0x80; /* IETF variant */↵
|
31 | secRandBuf16[10] |= 0x80; /* multicast bit */↵ | | 31 | secRandBuf16[10] |= 0x80; /* multicast bit */↵
|
32 | long mostSig = 0;↵ | | 32 | long mostSig = 0;↵
|
33 | for (int i = 0; i < 8; i++) {↵ | | 33 | for (int i = 0; i < 8; i++) {↵
|
34 | mostSig = (mostSig << 8) | (secRandBuf16[i] & 0xff);↵ | | 34 | mostSig = (mostSig << 8) | (secRandBuf16[i] & 0xff);↵
|
35 | }↵ | | 35 | }↵
|
36 | long leastSig = 0;↵ | | 36 | long leastSig = 0;↵
|
37 | for (int i = 8; i < 16; i++) {↵ | | 37 | for (int i = 8; i < 16; i++) {↵
|
38 | leastSig = (leastSig << 8) | (secRandBuf16[i] & 0xff);↵ | | 38 | leastSig = (leastSig << 8) | (secRandBuf16[i] & 0xff);↵
|
39 | }↵ | | 39 | }↵
|
40 | return (digits(mostSig >> 32, 8) + "-" + digits(mostSig >> 16, 4) + "-"↵ | | 40 | return (digits(mostSig >> 32, 8) + "-" + digits(mostSig >> 16, 4) + "-" //$NON-NLS-1$//$NON-NLS-2$↵
|
41 | + digits(mostSig, 4) + "-" + digits(leastSig >> 48, 4) + "-" + digits(↵ | | 41 | + digits(mostSig, 4) + "-" + digits(leastSig >> 48, 4) + "-" + digits( //$NON-NLS-1$//$NON-NLS-2$↵
|
42 | leastSig, 12));↵ | | 42 | leastSig, 12));↵
|
43 | }↵ | | 43 | }↵
|
|
44 | /** Returns val represented by the specified number of hex digits. */↵ | | 44 | /** Returns val represented by the specified number of hex digits. */↵
|
45 | private static String digits(long val, int digits) {↵ | | 45 | private static String digits(long val, int digits) {↵
|
46 | long hi = 1L << (digits * 4);↵ | | 46 | long hi = 1L << (digits * 4);↵
|
47 | return Long.toHexString(hi | (val & (hi - 1))).substring(1);↵ | | 47 | return Long.toHexString(hi | (val & (hi - 1))).substring(1);↵
|
48 | } | | 48 | }
|