JDK 26 与更早版本
Java 中的 UUID v7
JDK 26 可以用毫秒时间戳构造第 7 版 UUID。更早的 JDK 仍有 UUID.randomUUID(),那是第 4 版,所以第 7 版需要自己按字节组装。
生成 UUID
选择版本和数量,然后生成。
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 程序复制用的。