java uuid生成原理 为什么不会重复?
UUID (Universally Unique Identifier) 是一种128位的全局唯一标识符。UUID 的目的是让分布式系统中的所有元素都有唯一的标识符,而不会存在冲突。UUID 的标准由 RFC 4122 定义,常见的 UUID 表示格式为一组 32 个十六进制数字,以 8-4-4-4-12 的模式显示,如:550e8400-e29b-41d4-a716-446655440000。
UUID 有几个不同的版本,每个版本的生成方式不同,下面简要介绍几种常见的 UUID 生成原理:
UUIDv1(基于时间和节点):
UUIDv1 由时间戳、时钟序列和节点(通常是网络地址)组成。
时间戳表示自 1582-10-15 以来的 100 纳秒间隔数。
时钟序列用来防止因时钟回拨导致的冲突。
节点通常是设备的 MAC 地址。
这种生成方式确保了时间和空间的唯一性。
UUIDv2(基于 DCE 安全):
类似 UUIDv1,但加入了 POSIX UID/GID 的片段,用于分布式计算环境(DCE)。
并不常用。
UUIDv3(基于名称的 MD5 哈希):
通过对命名空间标识符和名字进行 MD5 哈希运算生成。
可以根据相同的名字和命名空间生成一致的 UUID。
哈希算法保证了 UUID 的唯一性。
UUIDv4(随机生成):
UUIDv4 完全通过随机数生成,其中有 6 位固定表示版本号和变体信息。
其生成的唯一性依赖于随机数生成器的质量。
UUIDv5(基于名称的 SHA-1 哈希):
类似 UUIDv3,但使用 SHA-1 哈希算法。
相较于 UUIDv3 的 MD5 哈希算法,更加安全和唯一。
在 Java 中生成 UUID
Java 提供了生成 UUID 的工具类 java.util.UUID,可以很方便地生成 UUIDv4。例如:
示例:生成 UUIDv4
import java.util.UUID;
public class UUIDExample {
public static void main(String[] args) {
// 生成一个随机的 UUID(UUIDv4)
UUID uuid = UUID.randomUUID();
System.out.println("生成的 UUID: " + uuid.toString());
}
}
对于其他版本的 UUID,如 UUIDv3 和 UUIDv5,可以通过使用相应的哈希算法和命名空间来手动实现。
示例:生成 UUIDv3
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class UUIDExample {
public static void main(String[] args) throws NoSuchAlgorithmException {
// 示例命名空间和名称
String namespace = "example-namespace";
String name = "example-name";
// 生成 UUIDv3
UUID uuid = generateUUIDv3(namespace, name);
System.out.println("生成的 UUIDv3: " + uuid.toString());
}
public static UUID generateUUIDv3(String namespace, String name) throws NoSuchAlgorithmException {
// 获取 MD5 哈希算法实例
MessageDigest md = MessageDigest.getInstance("MD5");
// 组合命名空间和名称
md.update(namespace.getBytes(StandardCharsets.UTF_8));
md.update(name.getBytes(StandardCharsets.UTF_8));
// 计算哈希值
byte[] hash = md.digest();
// 调整字节以符合 UUIDv3 的版本和变体
hash[6] &= 0x0f;
hash[6] |= 0x30; // 设置 UUID 版本为 3
hash[8] &= 0x3f;
hash[8] |= 0x80; // 设置 UUID 变体为 IETF
// 转换哈希值为 UUID
long msb = 0;
long lsb = 0;
for (int i = 0; i < 8; i++)
msb = (msb << 8) | (hash[i] & 0xff);
for (int i = 8; i < 16; i++)
lsb = (lsb << 8) | (hash[i] & 0xff);
return new UUID(msb, lsb);
}
}
正文到此结束
- 本文标签: java
- 本文链接: https://codeis.run/article/java-uuid-yuanli
- 版权声明: 本文由醒醒原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权