原创

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);
    }
}
正文到此结束