package com.fenbi.orion.notifypush.server.util;
import com.fenbi.common.util.RandomUtils;
/**
* Java 原生的UUID为36位 or 32位,太长.
* 这里提供一个位数较短的UUID.
* <p>
* UUID生成规则,当前时间减去'纪元时间'的毫秒数 + 三位随机数生成的long,转变成62进制的String类型.
* <p>
* 当前配置可满足3年内每毫秒千分之一的碰撞.可以修改配置实现更久or更大的碰撞。
* <p>
* 实测长度8位
*
* @author libing02 , on 11月 20, 2019.
*/
public class ShortUUID {
private static final char[] digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
// 2019-11-15 17:00:00
private static final long ERA_TIME = 1573808400000L;
// UUID一次轮回的指数. 12则为大概30年左右,11则为3年左右. 业务逻辑短时间内唯一即可
private static final int TIME_LOOP_INDEX = 11;
// 碰撞指数.毫秒下千分之一够用了
private static final int COLLISION_INDEX = 999;
public static String randomUUID() {
long passTime = System.currentTimeMillis() - ERA_TIME;
// 反转后右补0
StringBuilder stringBuilder = new StringBuilder(String.valueOf(passTime)).reverse();
while (stringBuilder.length() < TIME_LOOP_INDEX) {
stringBuilder.append('0');
}
long l = Long.parseLong(stringBuilder.substring(0, TIME_LOOP_INDEX));
return toString(l, digits.length) + toString(RandomUtils.ranInt(COLLISION_INDEX), digits.length);
}
/**
* 将10进制转换成任意进制,
* 照着Long原生的进制转换写的,原生最大支持到32进制,这里支持到62进制,理论上可以扩展digits数组实现更高
*/
public static String toString(long i, int radix) {
if (radix < 2 || radix > digits.length) {
radix = 10;
}
if (radix <= 32) {
return Long.toString(i, radix);
}
final int size = 65;
int charPos = 64;
char[] buf = new char[size];
boolean negative = (i < 0);
if (!negative) {
i = -i;
}
while (i <= -radix) {
buf[charPos--] = digits[(int) (-(i % radix))];
i = i / radix;
}
buf[charPos] = digits[(int) (-i)];
if (negative) {
buf[--charPos] = '-';
}
return new String(buf, charPos, (size - charPos));
}
}
更短且不失高效的UUID生成算法
猜你喜欢
转载自www.cnblogs.com/acbingo/p/11900317.html
今日推荐
周排行