• 从零开发短视频电商 UUID的5个版本和缩短长度


    定义

    UUID是由一个16进制下的32位数所构成,故UUID理论上的总数为1632 =2128,约等于3.4 x 1038。也就是说若每纳秒(ns)产生1万亿个UUID,要花100亿年才会将所有UUID用完。

    UUID的标准型式包含32个16进制数字,分为五段,形式为 8-4-4-4-12 的32个字符。示例:

    550e8400-e29b-41d4-a716-446655440000

    格式

    在其规范的文本表示中,UUID 的 16 个 8 位字节表示为 32 个十六进制(基数16)数字,显示在由连字符分隔 ‘-’ 的五个组中,“8-4-4-4-12” 总共 36 个字符(32 个字母数字字符和 4 个连字符)。

    例如:

    123e4567-e89b-12d3-a456-426655440000
    xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

    M表示 UUID 版本, N的一至三个最高有效位表示 UUID 变体。在例子中,M1Na,这意味着此 UUID 是“变体1”、“版本1”UUID;即基于时间的 DCE/RFC 4122 UUID。

    版本由 M 字符串中指示

    • 版本1 - UUID 是根据时间和 节点ID(通常是MAC地址)生成;

    • 版本2 - UUID是根据标识符(通常是组或用户ID)、时间和节点ID生成;

    • 版本3、版本5 - 确定性UUID 通过散列(hashing)名字空间(namespace)标识符和名称生成;

    • 版本4 - UUID 使用随机性或伪随机性生成。

    N那个位置,只会是8,9,a,b

    M那个位置,代表版本号,由于UUID的标准实现有5个版本,所以只会是1,2,3,4,5

    版本

    V1 时间+MAC地址

    版本1的UUID,是根据 60-bit 的时间戳 和 节点(生成UUID的计算机)的 48-bitMAC地址而生成的。

    优点:由于在算法中使用了MAC地址,这个版本的UUID可以保证在全球范围的唯一性。

    缺点:因为它暴露了电脑的MAC地址和生成这个UUID的时间,这就是这个版本UUID被诟病的地方,使用MAC地址会带来安全性问题。一台机器部署多个实例可能会出现重复。

    现在基本没人使用

    V2 时间+MAC地址 DCE安全版本

    DCE(Distributed Computing Environment)安全的UUID。和基于时间的UUID算法相同,但会把时间戳的前4位置换为POSIX的UID或GID。

    不过,在UUID的规范里面没有明确地指定,所以基本上所有的UUID实现都不会实现这个版本。

    V3 V5 基于名字空间名称

    版本3”和“版本5”的 UUID 被生成散列(hashing)一个名字空间标识符和一个名称。“版本3”使用 MD5 作为散列算法,“版本5”使用 SHA1

    V4 随机UUID

    根据随机数,或者伪随机数生成UUID。这种UUID产生有一定的重复概率但是极低,忽略不计;目前使用最多的版本

    Java只支持生成版本3和版本4的UUID

    V4 随机UUID,UUID.randomUUID().toString()

    V4 随机UUID重复概率问题?

    V4随机版本有一定的重复概率但是极低,直接上结论,来着维基百科

    在 103 万亿 个 版本4 UUID 中找到重复的概率是(十亿分之一)。

    UUID缩短长度

    原始UUID的是32个字符长度 16进制存储,现在改为64进制存储,即base64,需要22个字符长度。即长度从原始的36降低到22,但是核心没变,只是变了展现形式。

    原始的Base64包含+/,其在url中会转义,但是使用url安全的则会自动替换为- _

    方式一 org.apache.commons.codec.binary.Base64

    	import org.apache.commons.codec.binary.Base64;
    
        public static String uuidToBase64(String uuidStr) {
            UUID uuid = UUID.fromString(uuidStr);
            ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
            bb.putLong(uuid.getMostSignificantBits());
            bb.putLong(uuid.getLeastSignificantBits());
            return Base64.encodeBase64URLSafeString(bb.array());
        }
    
            public static String uuidFromBase64(String base64) {
            byte[] bytes = Base64.decodeBase64(base64);
            ByteBuffer bb = ByteBuffer.wrap(bytes);
            UUID uuid = new UUID(bb.getLong(), bb.getLong());
            return uuid.toString();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    方式二 JDK8 java.util.Base64

    	import java.nio.ByteBuffer;
    	import java.util.Base64;
    	import java.util.UUID;
    
        private static final Base64.Encoder BASE64_URL_ENCODER = Base64.getUrlEncoder().withoutPadding();
        private static final Base64.Decoder BASE64_URL_DECODER = Base64.getUrlDecoder();
    
        public static String uuidToBase64(String uuidStr) {
            UUID uuid = UUID.fromString(uuidStr);
            ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
            bb.putLong(uuid.getMostSignificantBits());
            bb.putLong(uuid.getLeastSignificantBits());
            return BASE64_URL_ENCODER.encodeToString(bb.array());
        }
    
        public static String uuidFromBase64(String base64) {
            byte[] bytes = BASE64_URL_DECODER.decode(base64);
            ByteBuffer bb = ByteBuffer.wrap(bytes);
            UUID uuid = new UUID(bb.getLong(), bb.getLong());
            return uuid.toString();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    参考:

    • https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E5%94%AF%E4%B8%80%E8%AF%86%E5%88%AB%E7%A0%81
    • https://stackoverflow.com/questions/772802/storing-uuid-as-base64-string
  • 相关阅读:
    信息学奥赛一本通:1119:矩阵交换行
    Day9——用栈实现队列、用队实现拟栈
    H3C S5820V2_5830V2交换机IRF2堆叠后升级方法
    山西828 B2B企业节进行时 华为携手合作伙伴共探数字化转型
    Unity 阴影——阴影平坠(Shadow pancaking)
    BAT034:批处理打开电脑常用功能面板
    为什么使用KT6368A蓝牙芯片用app连接,基本都在5分钟左右后断开
    深入剖析 Python 最常用数据结构:列表(List) & 元组(Tuple)
    Codeforces Round #833 (Div. 2)A — C
    【C++风云录】发现天空之美:使用C++库进行气象图像处理与分析
  • 原文地址:https://blog.csdn.net/abu935009066/article/details/126483201