UUID压缩

UUID是通用唯一识别码,用于确保分布式系统中元素的唯一性。它由日期时间、时钟序列和机器识别号组成,通常为36个字符。本文探讨了通过64进制转换对UUID进行压缩的方法,将128位的UUID缩短约1/3的长度,从而减少存储和传输成本。Java代码实现被提及。

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

关于UUID概念,截取百度百科简单说明一下:

UUID(Universally Unique Identifier)通用唯一识别码,目的是让分布式系统中的所有元素,都能有唯一的辨识信息,可作为数据库id等。由三部分组成:
(1)当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
(2)时钟序列。
(3)全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。
UUID的唯一缺陷在于生成的结果串会比较长。

wiki上对UUID的定义:

A universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems.
一个普遍唯一的标识符(UUID)是一个128位的数字。

这里的128位意为:由一组32位数的16进制数字所构成,而一个16进制数可以用4位来表示,故32*4=128。我们用JDK中的UUID工具类取得一个UUID

UUID uu=UUID.randomUUID();
System.out.println(uu.toString());

输出
e1214bfc-bc36-494a-8541-697355796bca

由五部分组成,用-进行连接。总共为36个字符,占用2byte*36个字节,但是通常情况下,我们并不需要-符号,而是需要e1214bfcbc36494a8541697355796bca这样的字符串,所以我们先去除不必要字符,进行第一步压缩:

String uuid = UUID.randomUUID().toString().replaceAll("-","");  
System.out.println(uuid);  

上面提到,uuid是用32个16进制数字组成,每个16进制可用4bit来表示,总共是128bit。那么我们就会想到,如果用64进制数字来表示,每个数字用6bit来表示,那么uuid的长度就变短了。大致思路:128/6=21余2,剩下的2位也记为一位64进制数,那么总共就是22个64进制数,相比较16进制,压缩了1/3。Java代码实现:

//我们先定义64进制由哪些字符表示
private static final char[] _UUID64 = 
    "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".toCharArray();
/**
     * @return java.lang.String
     * @Description 用64进制来表示UUID
     * @Param uu 传入由JDK获得的uuid对象 
     **/
    public static String UUID64(java.util.UUID uu) {
        //用于存放压缩后的uuid值
        char[] uuid64 = new char[22];
        //压缩后数组偏移指针
        int index = 0;
        //获取源uuid的前64位和后64位(返回的是10进制数)
        long most = uu.getMostSignificantBits();
        long least = uu.getLeastSignificantBits();
        //进行与运算(&)的基值,由于我们使用64进制,即可用6bit表示,所以我们取63(111111)来进行切割
        long mask = 63L;

        //将前64位切割10次,还剩余4位参与后64位切割
        for (int off = 58; off >= 4; off -= 6) {
            //截取高位后不要忘记无符号右移回对应位数,因为most和least可能是负数,如果是用>>会可能报数组下标溢出错误。
            long hex = (most & (mask << off)) >>> off;
            //用64进制来表示
            uuid64[index++] = _UUID64[(int) hex];
        }
        //前64位的低4位和后64位的高2位拼接
        int i=(int) (((most & 15) << 2) | ((least & (3 << 62))>>>62));
        uuid64[index++] = _UUID64[i];
        //前64位剩余的62位先分割10次,剩余2位单独处理
        for (int off = 56; off >= 2; off -= 6) {
            long hex = (least & (mask << off)) >>> off;
            uuid64[index++] = _UUID64[(int) hex];
        }
        //处理剩余2位
        uuid64[index] = _UUID64[(int) least & 3];
        //返回字符串
        return uuid64.toString();
    }

加个图帮助理解:
uuid

### 自动生成UUID的Java示例 在Java中,可以通过`java.util.UUID`类中的静态方法`randomUUID()`来生成一个随机的UUID。此方法会返回一个表示随机生成UUID的对象[^2]。 以下是完整的代码示例: ```java import java.util.UUID; public class UUIDExample { public static void main(String[] args) { // 调用UUID类的randomUUID()方法生成一个随机UUID UUID uuid = UUID.randomUUID(); // 输出原始形式的UUID System.out.println("随机生成的UUID:" + uuid); // 如果需要去掉分隔符'-'并转换为纯字符串形式 String strUuid = uuid.toString().replaceAll("-", ""); System.out.println("无横线的UUID:" + strUuid); } } ``` 运行上述代码后,将会输出如下内容(每次执行的结果可能不同): ``` 随机生成的UUID:13bf135c-e8b1-481e-9329-a5e3b62171ae 无横线的UUID:13bf135ce8b1481e9329a5e3b62171ae ``` 如果希望进一步缩短UUID至固定长度(如8位),可以采用一种简化的方式处理。以下是一个生成短UUID的例子[^3]: ```java import java.util.UUID; import java.math.BigInteger; public class ShortUUIDGenerator { public static void main(String[] args) { String shortUUID = generateShortUUID(); System.out.println("Generated Short UUID: " + shortUUID); } public static String generateShortUUID() { // 生成标准UUID UUID uuid = UUID.randomUUID(); // 将UUID转为BigInteger进行数值操作 BigInteger bigInt = new BigInteger(uuid.toString().replace("-", ""), 16); // 取模运算限定到64位整数范围内,并转化为16进制字符串 String shortUUID = bigInt.mod(new BigInteger("FFFFFFFFFFFFFFFF", 16)).toString(16).toUpperCase(); // 补齐到8位长度 return String.format("%08s", shortUUID); } } ``` 该程序通过取模和格式化操作将标准UUID压缩成更简洁的形式,适用于某些特定场景下的需求[^3]。 #### 注意事项 虽然短UUID更加紧凑,但由于其减少了唯一性保障,在实际应用中需谨慎评估是否满足业务所需的冲突概率要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值