更短且不失高效的UUID生成算法
Java原生的UUID长度为36位,嫌长
这里自己实现了一套自己的算法,来生成较短的UUID
由雪花算法启发而来,
大致原理是利用时间戳+随机值做值,然后转换成62进制(当然这个进制数你也可以搞成更多)
有一些参数可以控制一些行为,都在注释里了
你可以自己修改digits数组,乱乱序啥的,混淆一下,随机性可能更好一些
/**
* Java 原生的UUID为36位 or 32位,太长. 这里提供一个位数较短的UUID.
* <p>
* UUID生成规则,当前时间减去'零时'的毫秒数 + N位随机数,转变成62进制的String类型.
* <p>
* 当前配置可满足30年内每毫秒10^9分之一的碰撞.
* <p>
* 实测现在长度为13位,想要更短的话可以调整下方的几个参数
*
* @author libing02 , on 11月 20, 2019.
*/
public class ShortUUID {
/**
* digits还可以扩,但是不要包含下面的SEPARATOR
* <p>
* 也可以替换一个"乱序"digits排列,最终使uuid看起来不是有序的.
* <p>
* 一旦用到生产环境,digits就不要再变动了,否则会出现重复
* <p>
*/
private static final char[] digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
.toCharArray();
private static final char SEPARATOR = '_';
// 2019-11-15 17:00:00
private static final long ERA_TIME = 1573808400000L;
// UUID一次轮回的指数. 12则为大概30年左右,11则为3年左右. 13就是300年
private static final int TIME_LOOP_INDEX = 12;
// 碰撞指数.毫秒下万万分之一
private static final int COLLISION_INDEX = 99999999;
private static final boolean MIX_UP = true;
public static String randomUUID() {
long passTime = System.currentTimeMillis() - ERA_TIME;
long l = passTime;
// 反转主要是为了让uuid看起来不是递增的
// 但这也会导致出现极小概率不同时间的碰撞,所以建议优先选择不反转
if (MIX_UP) {
StringBuilder stringBuilder = new StringBuilder(String.valueOf(passTime)).reverse();
while (stringBuilder.length() < TIME_LOOP_INDEX) {
stringBuilder.append('0');
}
l = Long.parseLong(stringBuilder.substring(0, TIME_LOOP_INDEX));
}
return baseConversion(l, digits.length) + SEPARATOR +
baseConversion(RandomUtils.ranInt(COLLISION_INDEX), digits.length);
}
@Test
public void test() {
System.out.println(randomUUID());
}
/**
* 将10进制转换成任意进制,照着Long原生的进制转换写的,原生最大支持到32进制
* <p>
* 这里支持到更高进制,可以扩展digits数组实现更高
*
* @param i 十进制Long型
* @param radix 进制,[2-62]
* @return 转换后的String
*/
public static String baseConversion(long i, int radix) {
if (radix < 2 || radix > digits.length) {
radix = 10;
}
int charPos = digits.length * 2;
final int size = charPos + 1;
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生成算法的更多相关文章
- 一个UUID生成算法的C语言实现 --- WIN32版本 .
一个UUID生成算法的C语言实现——WIN32版本 cheungmine 2007-9-16 根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...
- 一个UUID生成算法的C语言实现——WIN32版本
源: 一个UUID生成算法的C语言实现——WIN32版本
- UUID 生成(源代码编译)
根据定义,UUID(Universally Unique IDentifier,也称GUID)在时间和空间都是唯一的.为保证空间的唯一性,每个UUID使用了一个48位的值来记录,一般是计算机的网卡地址 ...
- 分布式全局不重复ID生成算法
分布式全局不重复ID生成算法 算法全局id唯一id 在分布式系统中经常会使用到生成全局唯一不重复ID的情况.本篇博客介绍生成的一些方法. 常见的一些方式: 1.通过DB做全局自增操作 优点:简单.高 ...
- 分布式系统的唯一id生成算法你了解吗?
在分库分表之后你必然要面对的一个问题,就是id咋生成? 因为要是一个表分成多个表之后,每个表的id都是从1开始累加自增长,那肯定不对啊. 举个例子,你的订单表拆分为了1024张订单表,每个表的id都从 ...
- ES批量索引写入时的ID自动生成算法
对bulk request的处理流程: 1.遍历所有的request,对其做一些加工,主要包括:获取routing(如果mapping里有的话).指定的timestamp(如果没有带timestamp ...
- 使用深度学习检测DGA(域名生成算法)——LSTM的输入数据本质上还是词袋模型
from:http://www.freebuf.com/articles/network/139697.html DGA(域名生成算法)是一种利用随机字符来生成C&C域名,从而逃避域名黑名单检 ...
- 美团技术分享:深度解密美团的分布式ID生成算法
本文来自美团技术团队“照东”的分享,原题<Leaf——美团点评分布式ID生成系统>,收录时有勘误.修订并重新排版,感谢原作者的分享. 1.引言 鉴于IM系统中聊天消息ID生成算法和生成策略 ...
- 如何做系列(4)-微博URL短网址生成算法原理(java版、php版实现实例)
短网址(Short URL),顾名思义就是在形式上比较短的网址.通常用的是asp或者php转向,在Web 2.0的今天,不得不说,这是一个潮流.目前已经有许多类似服务,借助短网址您可以用简短的网址替代 ...
随机推荐
- Prometheus【node_exporter】+grafana监控云主机
下面说一下这个开源软件的安装实践过程,目标如下: 在监控服务器上安装prometheus 在被监控环境上安装exporter 安装grafana 在监控服务器上安装prometheus 开始安装pro ...
- C#-CMD
private static string InvokeCmd(string cmdArgs) { string Tstr = ""; Process p = new Proces ...
- 每天一道面试题LeetCode 80--删除排序数组中的重复项 II(python实现)
LeetCode 80--删除排序数组中的重复项 II 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输 ...
- 密码学系列之:NIST和SHA算法
目录 简介 SHA1 SHA2 SHA3 简介 SHA算法大家应该都很熟悉了,它是一个用来计算hash的算法,目前的SHA算法有SHA1,SHA2和SHA3种.这三种算法都是由美国NIST制定的. N ...
- spring.framework 版本从4.1.6.RELEASE升到5.0.20.RELEASE
将org.springframework 使用到的jar 版本号改为5.0.20.RELEASE后运行会报错: Servlet.service() for servlet [springmvc] in ...
- Git 系列教程(7)- 撤销操作
撤销操作 在任何一个阶段,你都有可能想要撤销某些操作 有些撤销操作是不可逆的 --amend 修补提交 有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了. 此时,就可以运行带有 -- ...
- java中基本数据类型、包装类及字符串之间的相互转换
基本数据类型:不支持面向对象的编程机制(没有属性和方法),即不支持面向对象,之所以提供8中基本数据类型,是为了方便常规数据的处理. 包装类:通过包装类可以将基本数据类型的值包装为引用数据类型的对象,使 ...
- Spring Cloud 升级之路 - 2020.0.x - 5. 理解 NamedContextFactory
spring-cloud-commons 中参考了 spring-cloud-netflix 的设计,引入了 NamedContextFactory 机制,一般用于对于不同微服务的客户端模块使用不同的 ...
- ln -s 新目录(最后一个目录新建images) 旧目录(删除最后的images目录)
sudo yum install libvirt virt-install qemu-kvm 默认安装会启用一个NAT模式的bridgevirbr0 启动激活libvirtd服务 systemctl ...
- Linux 系统定时任务:crontab,anacron
Linux 系统定时任务:crontab,anacron 一.Cron 服务 1. 启动服务 service cron start 2. 关闭服务 service cron stop 3. 重启服务 ...