关于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();
}
加个图帮助理解: