JDK 26 与更早版本

Java 中的 UUID v7

JDK 26 可以用毫秒时间戳构造第 7 版 UUID。更早的 JDK 仍有 UUID.randomUUID(),那是第 4 版,所以第 7 版需要自己按字节组装。

生成 UUID

版本

请填写 1 到 20 的整数。

生成使用浏览器里的 crypto.getRandomValues。结果不会上传,再次生成会换掉当前列表。

生成结果 0

选择版本和数量,然后生成。

    ofEpochMillis 会拒绝放不进 48 位的时间戳。如果要让同一毫秒内的多个值递增,请传入你已经做成单调的时间戳。这个方法自己不会做这件事。

    更早版本的示例复用一个 SecureRandom。每次调用都新建 SecureRandom 会多花播种时间。位操作和本站布局一致:rand_a 和 rand_b 是随机数,不是计数器。

    JDK 26

    import java.time.Instant;
    import java.util.UUID;
    
    UUID id = UUID.ofEpochMillis(Instant.now().toEpochMilli());

    更早的 JDK

    import java.security.SecureRandom;
    import java.util.UUID;
    
    final class UuidV7 {
      private static final SecureRandom RANDOM = new SecureRandom();
    
      static UUID create() {
        byte[] bytes = new byte[16];
        RANDOM.nextBytes(bytes);
        long ts = System.currentTimeMillis();
        bytes[0] = (byte) (ts >>> 40);
        bytes[1] = (byte) (ts >>> 32);
        bytes[2] = (byte) (ts >>> 24);
        bytes[3] = (byte) (ts >>> 16);
        bytes[4] = (byte) (ts >>> 8);
        bytes[5] = (byte) ts;
        bytes[6] = (byte) ((bytes[6] & 0x0f) | 0x70);
        bytes[8] = (byte) ((bytes[8] & 0x3f) | 0x80);
        long msb = 0;
        long lsb = 0;
        for (int i = 0; i < 8; i++) msb = (msb << 8) | (bytes[i] & 0xffL);
        for (int i = 8; i < 16; i++) lsb = (lsb << 8) | (bytes[i] & 0xffL);
        return new UUID(msb, lsb);
      }
    }

    常见问题

    哪个 JDK 有标准的 UUID v7 方法?

    JDK 26 增加了 UUID.ofEpochMillis(long)。它用你传入的毫秒时间戳构造第 7 版 UUID,并用加密随机源填上其余位。它不会替你把时间戳变成单调递增。

    更早的 JDK 呢?

    UUID.randomUUID() 是第 4 版。要做第 7 版,就把前 48 位设为 Unix 毫秒时间,版本半字节设为 7,两个变体位设为 10,其余位用 SecureRandom 填充。

    页面上的生成器是 Java 吗?

    不是。本页生成器在浏览器里用 crypto.getRandomValues 运行。Java 示例是给 Java 程序复制用的。