关于UUID

UUID是128位的通用唯一识别码,用于分布式系统中确保唯一标识。主要分为5个版本,每个版本有不同的生成算法。版本1和4保证唯一性,版本3和5则基于特定算法和命名空间生成固定UUID。Java中提供了UUID类,实现版本3和4的生成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

介绍

UUID(Universally Unique Identifier,通用唯一识别码),由32位16进制数字构成,二进制共128位

其目的是让分布式系统中的所有元素都能有唯一的识别信息。如此一来,每个人都可以创建不与其它人冲突的 UUID。

组成

UUID共有5部分组成:xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx,表现形式为8-4-4-4-12的32个字符。

如:df623885-68f9-47e0-b13c-bbd9600b6e71

  • 16进制数字M表示UUID版本,当前有5个版本:1,2,3,4,5。这5个版本使用不同算法,利用不同的信息产生UUID,各版本有各自优势,适用于不同情景。具体使用的信息:
  1. version 1, date-time & MAC address,当前时间戳 + MAC地址信息 生成
    1. 机器的MAC地址出厂后不能保证完全唯一,且之后 MAC 地址也可手动修改;
    2. MAC 地址的暴露会造成了隐私与安全问题;
    3. 若一台机子上的两个进程同时跑,有可能出现重复问题。
  2. version 2, date-time & group/user id
  3. version 3, MD5 hash & namespace
  4. version 4, pseudo-random number,伪随机数信息 生成,最频繁使用
  5. version 5, SHA-1 hash & namespace
  • 16进制数字N的二进制位一至四个最高有效位表示UUID变体(variant),有固定的两位10xx因此只可能取值8, 9, a, b
  • 因为时间戳和随机数的唯一性,版本1和版本4总是生成唯一的标识符。若希望对给定的一个字符串总是能生成相同的 UUID,使用版本3或版本5。

Java实现

java.util.UUID封装了UUID的实现,来看看其中方法:

/**
 * Static factory to retrieve a type 4 (pseudo randomly generated) UUID.
 *
 * The {@code UUID} is generated using a cryptographically strong pseudo
 * random number generator.
 *
 * @return  A randomly generated {@code UUID}
 */
public static UUID randomUUID() {
    // 与Random(弱伪随机数生成器)不一样,SecureRandom是强伪随机数生成器,结果不可预测
    // 使用SecureRandom生成随机数,替换version和variant就是 UUID
    SecureRandom ng = Holder.numberGenerator;

    byte[] randomBytes = new byte[16];
    ng.nextBytes(randomBytes);
    randomBytes[6]  &= 0x0f;  /* clear version        */
    randomBytes[6]  |= 0x40;  /* set to version 4     */
    randomBytes[8]  &= 0x3f;  /* clear variant        */
    randomBytes[8]  |= 0x80;  /* set to IETF variant  */
    return new UUID(randomBytes);
}

可以从randomUUID()看到,这个UUID应该是基于随机数的,版本4的UUID。

/**
 * Static factory to retrieve a type 3 (name based) {@code UUID} based on
 * the specified byte array.
 *
 * @param  name
 *         A byte array to be used to construct a {@code UUID}
 *
 * @return  A {@code UUID} generated from the specified array
 */
public static UUID nameUUIDFromBytes(byte[] name) {
    MessageDigest md;
    try {
        md = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException nsae) {
        throw new InternalError("MD5 not supported", nsae);
    }
    byte[] md5Bytes = md.digest(name);
    md5Bytes[6]  &= 0x0f;  /* clear version        */
    md5Bytes[6]  |= 0x30;  /* set to version 3     */
    md5Bytes[8]  &= 0x3f;  /* clear variant        */
    md5Bytes[8]  |= 0x80;  /* set to IETF variant  */
    return new UUID(md5Bytes);
}

可以从nameUUIDFromBytes(byte[] name)看到,这个UUID应该是基于MD5和命名空间,版本3的UUID。对于给定的字符串(name)总能生成相同的UUID。



参考:

什么是 UUID ?

UUID 的五个版本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值