Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8357251

Add Support for UUID Version 7 (UUIDv7) defined in RFC 9562

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P4 P4
    • 26
    • core-libs
    • None
    • source
    • minimal
    • Hide
      This is a new static method therefor there should be a minimal compatibility risk.
      Show
      This is a new static method therefor there should be a minimal compatibility risk.
    • Java API
    • SE

      Summary

      Add static factory methods UUID.unixEpochTimeMillis() and UUID.unixEpochTimeMillis(long) to create Version 7 UUIDs as defined in RFC 9562, embedding the current or supplied Unix time in milliseconds.

      Problem

      The JDK currently exposes static factories for version 3 (name-based) and version 4 (random) UUIDs via nameUUIDFromBytes() and randomUUID(), respectively. However, there is no built-in support for generating version 7 UUIDs, which incorporate millisecond-precision Unix timestamps and provide lexicographically sortable, time-ordered identifiers. UUIDv7 provides unique identifiers which can be sorted by creation time and has been of increasing popularity especialy in distributed systems.

      Solution

      Introduce two static factory methods in java.util.UUID:

      public static UUID unixEpochTimeMillis() -Generates a RFC 9562 Version 7 UUID using a current timestamp by combining System.currentTimeMillis() and System.nanoTime(), embedding the value in the first 48 bits, setting the version (7) and IETF variant fields, and filling remaining bits with cryptographically strong random data.

      public static UUID unixEpochTimeMillis(long timestamp) - Generates a Version 7 UUID using the provided Unix epoch timestamp in milliseconds (must fit within 48 bits). The method sets all other bits according to the v7 specification.

      The implementation ensures compliance with RFC 9562 section 5.4, with monotonicMS() mitigating issues from system clock granularity or backward jumps.

      Specification

      Update UUID.java spec with the following:

      diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java
      index 5961fce9cb2..e95e2d85218 100644
      --- a/src/java.base/share/classes/java/util/UUID.java
      +++ b/src/java.base/share/classes/java/util/UUID.java
      @@ -61,21 +61,22 @@
        * {@code UUID}.  The bit layout described above is valid only for a {@code
        * UUID} with a variant value of 2, which indicates the Leach-Salz variant.
        *
      - * <p> The version field holds a value that describes the type of this {@code
      - * UUID}.  There are four different basic types of UUIDs: time-based, DCE
      - * security, name-based, and randomly generated UUIDs.  These types have a
      - * version value of 1, 2, 3 and 4, respectively.
      + * <p> There are eight defined types of UUIDs, each identified by a version number:
      + * time-based (version 1), DCE security (version 2), name-based with MD5 (version 3),
      + * randomly generated (version 4), name-based with SHA-1 (version 5), reordered time-based (version 6),
      + * Unix epoch time-based (version 7), and custom-defined layout (version 8).
        *
        * <p> For more information including algorithms used to create {@code UUID}s,
        * see <a href="http://www.ietf.org/rfc/rfc4122.txt"> <i>RFC&nbsp;4122: A
        * Universally Unique IDentifier (UUID) URN Namespace</i></a>, section 4.2
        * &quot;Algorithms for Creating a Time-Based UUID&quot;.
        *
      - * @spec https://www.rfc-editor.org/info/rfc4122
      - *      RFC 4122: A Universally Unique IDentifier (UUID) URN Namespace
      + * @spec https://www.rfc-editor.org/rfc/rfc9562.html
      + *      RFC 9562 Universally Unique IDentifiers (UUIDs)
        * @since   1.5
        */
       public final class UUID implements java.io.Serializable, Comparable<UUID> {
      
      +    /**
      +     * Record a fixed point in nano-time corresponding to a fix point in System.currentTimeMillis()
      +     * and use the delta from the current nano-time as the current nano-time.
      +     */
      +    private static final long ORIGIN_MS = System.currentTimeMillis();
      
      +    /**
      +     * Static factory to create a version 7 (Unix epoch time-based) {@code UUID} with the current
      +     * Unix timestamp in milliseconds.
      +     *
      +     * The {@code UUID} embeds the current Unix Epoch timestamp in milliseconds using
      +     * {@link System#currentTimeMillis()} into the first 6 bytes, sets the version and
      +     * variant bits as per the specification and fills the remaining bytes with random
      +     * data from a cryptographically strong pseudo-random number generator.
      +     *
      +     * @return a {@code UUID} generated with the current Unix timestamp
      +     *
      +     * @spec https://www.rfc-editor.org/rfc/rfc9562.html
      +     *       RFC 9562 Universally Unique IDentifiers (UUIDs)
      +     */
      +    public static UUID unixEpochTimeMillis() {
      
      +    /**
      +     * Static factory to create a version 7 (time-based) {@code UUID} with a user-supplied
      +     * Unix timestamp in milliseconds.
      +     *
      +     * The {@code UUID} embeds the provided Unix Epoch timestamp in milliseconds into
      +     * the first 6 bytes, sets the version and variant bits as per the specification,
      +     * and fills the remaining bytes with random data from a cryptographically strong
      +     * pseudo-random number generator.
      +     *
      +     * @apiNote The timestamp must be a Unix Epoch timestamp in milliseconds in order
      +     * to be compliant with <a href="https://datatracker.ietf.org/doc/html/rfc9562">RFC 9562</a>.
      +     *
      +     * @param timestamp
      +     *        A Unix epoch timestamp in milliseconds which must fit in to 48 bits
      +     *
      +     * @return a {@code UUID} generated using the provided timestamp
      +     *
      +     * @throws IllegalArgumentException if the timestamp is negative or exceeds 48 bits
      +     *
      +     * @spec https://www.rfc-editor.org/rfc/rfc9562.html
      +     *       RFC 9562 Universally Unique IDentifiers (UUIDs)
      +     */
      +    public static UUID unixEpochTimeMillis(long timestamp) {
      
      @@ -322,6 +404,7 @@ public long getMostSignificantBits() {
            * <li>2    DCE security UUID
            * <li>3    Name-based UUID
            * <li>4    Randomly generated UUID
      +     * <li>7    Unix timestamp-based UUID
            * </ul>

            kfarrell Kieran Farrell
            webbuggrp Webbug Group
            Roger Riggs
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: