在使用到uuid的时候,往往头疼于它的长度(如1bfe50d8-544e-4e8a-95b8-199ceff15268),于是乎就有了改写uuid的各种方法

1.去除“-”的uuid

不觉得uuid很长,但是就是看着中间的“-”很难受,又占长度,简单直接点就是

UUID uuid = UUID.randomUUID();

uuid.toString.replace("-", "");

额,这种方法,简单粗暴不优雅,其实呢,还可以看看这个“-”是哪里来的:

public String toString() {

return (digits(mostSigBits >> 32, 8) + "-" +

digits(mostSigBits >> 16, 4) + "-" +

digits(mostSigBits, 4) + "-" +

digits(leastSigBits >> 48, 4) + "-" +

digits(leastSigBits, 12));

}

/** Returns val represented by the specified number of hex digits. */

private static String digits(long val, int digits) {

long hi = 1L << (digits * 4);

return Long.toHexString(hi | (val & (hi - 1))).substring(1);

}

源码里写的很清楚 是它自己干的,所以完全可以自己实现把“-”去掉(最终代码在后面)

2.21-22位的uuid

去掉“-”之后变成了9b8a013583ba42cba75a9f3d6471eb7a,是一个16进制的字符串,但还是太长

/*

* The most significant 64 bits of this UUID.

*

* @serial

*/

private final long mostSigBits;

/*

* The least significant 64 bits of this UUID.

*

* @serial

*/

private final long leastSigBits;

源码中的UUID类中的这两个long型属性(mostSigBits是前半部分,leastSigBits是后半部分),其实就代表了uuid,具体的字符串编码都是通过这两个long拼接起来的(不得不说,想法很鸡贼,正常看到的就是这两个的16进制字符串)。

有人说,那直接把“-”去掉使用base64转化成64进制的字符串不就短了很多了?是这样的,不过我们可以仿写base64的实现写个简单的(主要base64最后是拿“+”和“/”凑的64个,“/”在http传输中容易被误解析)

最终的UUIDUtils代码:

import java.util.Date;

import java.util.UUID;

/**

* Created by Kowalski on 2017/5/11

* Updated by Kowalski on 2017/5/11

*/

public final class UUIDUtils {

/**

* 采用URL Base64字符,即把“+/”换成“-_”

*/

private static final char[] digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_=".toCharArray();

/**21-22位UUID*/

public static String generateMost22UUID() {

UUID uid = UUID.randomUUID();

long most = uid.getMostSignificantBits();

char[] buf = new char[22];

int charPos = 22;

int radix = 1 << 6;

long mask = radix - 1;

do {

charPos--;

buf[charPos] = digits[(int)(most & mask)];

most >>>= 6;

} while (most != 0);

long least = uid.getLeastSignificantBits();

do {

charPos--;

buf[charPos] = digits[(int)(least & mask)];

least >>>= 6;

} while (least != 0);

return new String(buf, charPos, 22-charPos);

}

/**无 - UUID*/

public static String generateUUID() {

UUID uuid = UUID.randomUUID();

long most = uuid.getMostSignificantBits();

long least = uuid.getLeastSignificantBits();

return (digits(most >> 32, 8) +

digits(most >> 16, 4) +

digits(most, 4) +

digits(least >> 48, 4) +

digits(least, 12));

}

private static String digits(long val, int digits) {

long hi = 1L << (digits << 2);

return Long.toHexString(hi | (val & (hi - 1)));

}

/**22位UUID*/

public static String generateUUID22() {

UUID uuid = UUID.randomUUID();

long msb = uuid.getMostSignificantBits();

long lsb = uuid.getLeastSignificantBits();

char[] out = new char[24];

int tmp = 0, idx = 0;

// 循环写法

int bit = 0, bt1 = 8, bt2 = 8;

int mask = 0x00, offsetm = 0, offsetl = 0;

for(; bit < 16; bit += 3, idx += 4) {

offsetm = 64 - ((bit + 3) << 3);

offsetl = 0;

tmp = 0;

if(bt1 > 3) {

mask = (1 << 8 * 3) - 1;

} else if(bt1 >= 0) {

mask = (1 << 8 * bt1) - 1;

bt2 -= 3 - bt1;

} else {

mask = (1 << 8 * ((bt2 > 3) ? 3 : bt2)) - 1;

bt2 -= 3;

}

if(bt1 > 0) {

bt1 -= 3;

tmp = (int) ((offsetm < 0) ? msb : (msb >>> offsetm) & mask);

if(bt1 < 0) {

tmp <<= Math.abs(offsetm);

mask = (1 << 8 * Math.abs(bt1)) - 1;

}

}

if(offsetm < 0) {

offsetl = 64 + offsetm;

tmp |= ((offsetl < 0) ? lsb : (lsb >>> offsetl)) & mask;

}

if(bit == 15) {

out[idx + 3] = digits[64];

out[idx + 2] = digits[64];

tmp <<= 4;

} else {

out[idx + 3] = digits[tmp & 0x3f];

tmp >>= 6;

out[idx + 2] = digits[tmp & 0x3f];

tmp >>= 6;

}

out[idx + 1] = digits[tmp & 0x3f];

tmp >>= 6;

out[idx] = digits[tmp & 0x3f];

}

return new String(out, 0, 22);

}

public static void main(String... args) {

Date d5 = new Date();

for(int i = 0; i < 10000000; i++) {

generateUUID22();

}

Date d6 = new Date();

System.out.print(d6.getTime() - d5.getTime());

System.out.println("\n");

Date d1 = new Date();

for(int i = 0; i < 10000000; i++) {

generateMost22UUID();

}

Date d2 = new Date();

System.out.print(d2.getTime() - d1.getTime());

System.out.println("\n");

}

}

这种实现方式比用replace后再用base64转换速度要更快(接近一倍),这里都是为了保证uuid的精度实现的,对uuid精度要求较低的也可以使用其他位数更少的uuid变体,有更好方案的小伙伴来交流~

长度短点的uuid_UUID不失精度,长度改进相关推荐

  1. 关于基线长度对双天线GNSS测姿精度的影响

    文章目录 一.GNSS测姿原理 1. 载波相位双差求解基线向量 2. GNSS姿态角表示 二.基线长度对GNSS测姿精度的影响 三.GNSS定向产品精度描述实例 四.参考文献 在GNSS定向模块或者板 ...

  2. 短链接(ShortLink)系统遇到链接长度太短问题

    修改数据库长度 短连接系统中问题内容使用的是 MySQL 的 varchar(400) 字段存储,该字段最多会存储 400 个字符(汉字占三个字符). 在遇到缩短链接超长时,会自动截断调整.可通过以下 ...

  3. linux文件名长度限制6,linux和windows文件名长度限制问题

    文件名和目录名在操作系统中都有最大长度的限制,而且不同系统中的最大长度不同. 这些限制在Linux系统下可以通过修改系统内核修改这个限制. Linux文件名的长度限制是255个字符 windows下完 ...

  4. python3调用函数len结果不返回字符串长度_Python通过len函数返回对象长度

    英文文档: len(s) Return the length (the number of items) of an object. The argument may be a sequence (s ...

  5. java String长度与varchar长度匹配理解(字符和字节长度理解)

    java String长度与varchar长度匹配理解(字符和字节长度理解) string中的length()长度,返回的是char的数量,每个char可以存储世界上任何类型的文字和字符,一个char ...

  6. php获取字符串商都_php strlen获取字符串字节长度和mb_strlen获取字符串个数长度的区别(strlen获取中文长度)...

    strlen获取字符串字节长度和mb_strlen获取字符串个数长度的区别,如果字符串是数字或者英文字母组成的话,它们2个的结果上体现不出区别,可是如果字符串是汉字组成的话它们2个的结果差异很大 重点 ...

  7. mysql数据库char类型长度_mysql数据库设计字符类型及长度

    1.数字类型 小数的我就不聊了,因为有小数点的一般都是用字符串保存.关于整数,有几种可以选TINYINT.SMALLINT.MEDIUMINT.INT和BIGINT,分别占1.2.4.8字节.如果无符 ...

  8. android 分割字符 指定长度_[Android]TextUtils.ellipsize()截取指定长度字符串(附图文混排)...

    参考:http://zilla.blog.51cto.com/3095640/984775 效果图: 实现代码:// 监听布局变化,直接获取显示的长度 txtDescription.getViewTr ...

  9. 获取 Java list长度_String,数组,list集合长度的使用

    public class Use{ public static void main(String[] args){ int[] arr=new int[]{19,10,20,30,23,13}; // ...

最新文章

  1. Vue.js实现tab切换效果
  2. Visual Studio 2017 15.8 正式发布,测试速度提高 82%
  3. Android Multimedia框架总结(二十)MediaCodec状态周期及Codec与输入/输出Buffer过程(附实例)
  4. 【UE】UE4下载安装及测试demo
  5. 邹博机器学习代码分析(1)-线性回归
  6. onblur属性详解
  7. 【STM32学习笔记-03】ESP8266 访问心知天气API获取实时天气信息
  8. OpenGL ES (二)EGL介绍和使用
  9. 新年将至, 程序员如何以代码送出新春祝福
  10. 计算机 应用期刊模板下载
  11. hibernate一对一主键唯一外键关联(一)
  12. 湖南师范学院大学计算机等级考试,湖南师范大学计算机等级考试时间
  13. Jenkins无法启动:com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy
  14. select下拉框添加搜索功能
  15. 来自鹅厂的面试经验(干货)
  16. 数据分析真题日刷 | 商汤科技2018校招C++/算法开发/大数据/后端/运维/测试/数据挖掘开发工程师笔试第二场
  17. 周鸿祎区块链五大缺点, 区块链的100个问题
  18. 《谦逊的问讯》三步实用指南
  19. 联想服务器安全配置文件,适用于台式机的 Lenovo Service Engine(LSE)BIOS安全公告...
  20. 如何使用maven给Java打包

热门文章

  1. [转]企业网站首页设计常见的6种布局方式
  2. PLSQL Developer 特点
  3. CCF202009-4 星际旅行(100分题解链接)
  4. HDU2156 分数矩阵【数学计算+水题】
  5. HDU2153 仙人球的残影【数学计算+水题】
  6. HDU1215 七夕节【水题】
  7. python 运算符优先级、Chaining comparison operators
  8. 编码 —— 差错检验
  9. 稀疏编码(sparse code)与字典学习(dictionary learning)
  10. 商场内自动扶梯的研究