public final class UIDGenerator
extends java.lang.Object
Depending on the requested type of ID, this class will either use
UUID.randomUUID() or its own unique ID generator. This implementation
generates unique IDs based on the assumption that the following triplet is
unique:
Considering that these three numbers are represented as long
values, these assumptions are correct because:
Before building an ID from this triplet, the implementation will XOR the three values with random values calculated once when the class is loaded. This transformation preserves the uniqueness of the calculated triplet and serves several purposes:
| Modifier and Type | Field and Description |
|---|---|
private static long |
seqXorOperand |
private static long |
startTimeXorOperand |
private static long |
threadIdXorOperand |
private static java.lang.ThreadLocal |
triplet
Thread local that holds the triplet described in the Javadoc of this
class.
|
| Modifier | Constructor and Description |
|---|---|
private |
UIDGenerator() |
| Modifier and Type | Method and Description |
|---|---|
static java.lang.String |
generateContentId()
Generates a unique ID suitable for usage as a MIME content ID.
|
private static void |
generateHex(java.lang.StringBuilder buffer)
Generate a unique ID as hex value and add it to the given buffer.
|
static java.lang.String |
generateMimeBoundary()
Generates a MIME boundary.
|
static java.lang.String |
generateUID()
Generate a general purpose unique ID.
|
static java.net.URI |
generateURN()
Generate a URN with uuid NID (namespace identifier).
|
static java.lang.String |
generateURNString()
Generate a URN with uuid NID (namespace identifier).
|
private static void |
writeReverseLongHex(long value,
java.lang.StringBuilder buffer) |
private static final long startTimeXorOperand
private static final long threadIdXorOperand
private static final long seqXorOperand
private static final java.lang.ThreadLocal triplet
private static void writeReverseLongHex(long value,
java.lang.StringBuilder buffer)
private static void generateHex(java.lang.StringBuilder buffer)
buffer - public static java.lang.String generateContentId()
RFC2045 (MIME) specifies that the value of the Content-ID header must match the msg-id production, which is defined by RFC2822 as follows:
msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
id-left = dot-atom-text / no-fold-quote / obs-id-left
id-right = dot-atom-text / no-fold-literal / obs-id-right
dot-atom-text = 1*atext *("." 1*atext)
atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&"
/ "'" / "*" / "+" / "-" / "/" / "=" / "?"
/ "^" / "_" / "`" / "{" / "|" / "}" / "~"
In addition, RFC2392 specifies that when used in an URL with scheme
"cid:", the content ID must be URL encoded. Since not all implementations
handle this correctly, any characters considered "unsafe" in an URL (and
requiring encoding) should be avoided in a content ID.
This method generates content IDs that satisfy these requirements. It guarantees a high level of uniqueness, but makes no provisions to guarantee randomness. The implementation is thread safe, but doesn't use synchronization.
public static java.lang.String generateMimeBoundary()
Valid MIME boundaries are defined by the following production in RFC2046:
boundary := 0*69<bchars> bcharsnospace
bchars := bcharsnospace / " "
bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
"+" / "_" / "," / "-" / "." /
"/" / ":" / "=" / "?"
It should be noted that the boundary in general will also appear as a parameter in the content type of the MIME package. According to RFC2045 (which defines the Content-Type header), it will require quoting if it contains characters from the following production:
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <"> /
"/" / "[" / "]" / "?" / "="
This method produces a boundary that doesn't contain any of these characters and therefore doesn't need to be quoted. To avoid accidental collisions, the returned value is unique and doesn't overlap with any other type of unique ID returned by methods in this class. The implementation is thread safe, but doesn't use synchronization.
public static java.lang.String generateUID()
The fact that this method doesn't guarantee randomness implies that the generated IDs are predictable and must not be used in contexts where this would cause a security vulnerability. In particular, this method should not be used to generate the following kind of IDs:
public static java.lang.String generateURNString()
public static java.net.URI generateURN()
generateURNString(), but returns a URI object.