Class UIDGenerator


  • public final class UIDGenerator
    extends Object
    Contains utility methods to generate unique IDs of various kinds.

    Depending on the requested type of ID, this class will either use UUID.randomUUID() (or an equivalent algorithm) or its own unique ID generator. This implementation generates unique IDs based on the assumption that the following triplet is unique:

    1. The thread ID.
    2. The timestamp in milliseconds when the first UID is requested by the thread.
    3. A per thread sequence number that is incremented each time a UID is requested by the thread.

    Considering that these three numbers are represented as long values, these assumptions are correct because:

    • The probability that two different threads with the same ID exist in the same millisecond interval is negligibly small.
    • One can expect that no thread will ever request more than 2^64 UIDs during its lifetime.

    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:

    • It reduces the probability that the same ID is produces by two different systems, i.e. it increases global uniqueness.
    • It adds entropy, i.e. it makes an individual ID appear as random. Indeed, without the XOR transformation, a hexadecimal representation of the triplet would in general contain several sequences of '0'.
    • It prevents the implementation from leaking information about the system state.
    • Method Detail

      • generateContentId

        public static String generateContentId()
        Generates a unique ID suitable for usage as a MIME content ID.

        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.

        Returns:
        The generated content ID. Note that this value does not include the angle brackets of the msg-id production, but only represents the bare content ID.
      • generateMimeBoundary

        public static String generateMimeBoundary()
        Generates a MIME boundary.

        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.

        Returns:
        the generated MIME boundary
      • generateUID

        public static String generateUID()
        Generate a general purpose unique ID. The returned value is the hexadecimal representation of a 192 bit value, i.e. it is 48 characters long. The implementation guarantees a high level of uniqueness, but makes no provisions to guarantee randomness. It is thread safe, but doesn't use synchronization.

        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:

        • Session IDs.
        • Message IDs used in WS-Addressing.
        Returns:
        the generated unique ID
      • generateURNString

        public static String generateURNString()
        Generate a URN with uuid NID (namespace identifier). These URNs have the following form: urn:uuid:dae6fae1-93df-4824-bc70-884c9edb5973. The UUID is generated using a cryptographically strong pseudo random number generator.
        Returns:
        the generated URN
      • generateURN

        public static URI generateURN()
        Generate a URN with uuid NID (namespace identifier). This method does the same as generateURNString(), but returns a URI object.
        Returns:
        the generated URN