java 生成20位唯一ID
方法一:
https://blog.csdn.net/weixin_36751895/article/details/70331781
由于开发的需要,需要生成20位的长度的数字组成的id,首先要满足唯一性,那样的话就需要使用到时间戳来生成,java生成的时间戳是毫秒级的,理论上还是会发生产生相同的id,这是一件很头疼的一件事。
1、解决思路一:
在生成的13位长度的时间戳上面加上3位的自曾数
2017+1492764117143+XXX
代码如下:
package my;
import java.text.SimpleDateFormat;
/**
* 获取20位随机数
* 4位年份+13位时间戳+3位随机数
* @author yuyu
*/
public class GetTime {
public static void main(String[] args) {
//调用生成id方法
System.out.println(getGuid());
}
/**
* 20位末尾的数字id
*/
public static int Guid=100;
public static String getGuid() {
GetTime.Guid+=1;
long now = System.currentTimeMillis();
//获取4位年份数字
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy");
//获取时间戳
String time=dateFormat.format(now);
String info=now+"";
//获取三位随机数
//int ran=(int) ((Math.random()*9+1)*100);
//要是一段时间内的数据连过大会有重复的情况,所以做以下修改
int ran=0;
if(GetTime.Guid>999){
GetTime.Guid=100;
}
ran=GetTime.Guid;
return time+info.substring(2, info.length())+ran;
}
}
输出如下:
-
20171492765221643100
-
20171492765422922101
-
20171492765429776102
*但是这样还是会有重复调用的时候随机数一样的情况,但是这样的概率会很小很小,但是理论上是有可能出现的,但在实际开发中不会达到如此高的运行速度,这样产生的id也是可以唯一的
方法二:
https://blog.csdn.net/baidu_25310663/article/details/45243853
package net.jeeshop.core.util;
import java.util.Random;
public class RandomId {
private Random random;
private String table;
public RandomId() {
random = new Random();
table = "0123456789";
}
public String randomId() {
int id=random.nextInt(10);
String ret = null,
num = String.format("%05d", id);
int key = random.nextInt(10),
seed = random.nextInt(100);
Caesar caesar = new Caesar(table, seed);
num = caesar.encode(key, num);
ret = num
+ String.format("%01d", key)
+ String.format("%02d", seed);
return ret;
}
public static void main(String[] args) {
RandomId r = new RandomId();
for (int i = 0; i < 30; i += 1) {
}
System.out.println(r.randomId());
r.randomId();
}
public class Caesar {
private String table;
private int seedA = 1103515245;
private int seedB = 12345;
public Caesar(String table, int seed) {
this.table = chaos(table, seed, table.length());
}
public Caesar(String table) {
this(table, 11);
}
public Caesar() {
this(11);
}
public Caesar(int seed) {
this("ABCDEFGHIJKLMNOPQRSTUVWXYZ", seed);
}
public char dict(int i, boolean reverse) {
int s = table.length(), index = reverse ? s - i : i;
return table.charAt(index);
}
public int dict(char c, boolean reverse) {
int s = table.length(), index = table.indexOf(c);
return reverse ? s - index : index;
}
public int seed(int seed) {
long temp = seed;
return (int)((temp * seedA + seedB) & 0x7fffffffL);
}
public String chaos(String data, int seed, int cnt) {
StringBuffer buf = new StringBuffer(data);
char tmp; int a, b, r = data.length();
for (int i = 0; i < cnt; i += 1) {
seed = seed(seed); a = seed % r;
seed = seed(seed); b = seed % r;
tmp = buf.charAt(a);
buf.setCharAt(a, buf.charAt(b));
buf.setCharAt(b, tmp);
}
return buf.toString();
}
public String crypto(boolean reverse,
int key, String text) {
String ret = null;
StringBuilder buf = new StringBuilder();
int m, s = table.length(), e = text.length();
for(int i = 0; i < e; i += 1) {
m = dict(text.charAt(i), reverse);
if (m < 0) break;
m = m + key + i;
buf.append(dict(m % s, reverse));
}
if (buf.length() == e)
ret = buf.toString();
return ret;
}
public String encode(int key, String text) {
return crypto(false, key, text);
}
public String decode(int key, String text) {
return crypto(true , key, text);
}
// public static void main(String[] args) {
// Caesar caesar = new Caesar();
// String data = caesar.encode(32, "APPLE");
// caesar.decode(32, data);
// }
}
}
方法三:
https://www.aliyun.com/jiaocheng/279704.html
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @ClassName: MakeOrderNum
* @CreateTime 2015年9月13日 下午4:51:02
* @author : mayi
* @Description: 订单号生成工具,生成非重复订单号,理论上限1毫秒1000个,可扩展
**/
public class MakeOrderNum {
/**
* 锁对象,可以为任意对象
*/
private static Object lockObj = "lockerOrder";
/**
* 订单号生成计数器
*/
private static long orderNumCount = 0L;
/**
* 每毫秒生成订单号数量最大值
*/
private int maxPerMSECSize=999;
/**
* 生成非重复订单号,理论上限1毫秒1000个,可扩展
* @param tname 测试用
*/
public void makeOrderNum(String tname) {
try {
// 最终生成的订单号
String finOrderNum = "";
synchronized (lockObj) {
// 取系统当前时间作为订单号变量前半部分,精确到毫秒
long nowLong = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
// 计数器到最大值归零,可扩展更大,目前1毫秒处理峰值1000个,1秒100万
if (orderNumCount > maxPerMSECSize) {
orderNumCount = 0L;
}
//组装订单号
if (orderNumCount < 10) {
finOrderNum = nowLong + "00" + orderNumCount;
}
if (orderNumCount > 9 &;&; orderNumCount < 100) {
finOrderNum = nowLong + "0" + orderNumCount; }
if (orderNumCount > 99) {
finOrderNum = nowLong + "" + orderNumCount;
}
orderNumCount++;
System.out.println(finOrderNum + "--" + Thread.currentThread().getName() + "::" + tname );
// Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 测试多线程调用订单号生成工具
try {
for (int i = 0; i < 200; i++) {
Thread t1 = new Thread(new Runnable() {
public void run() {
MakeOrderNum makeOrder = new MakeOrderNum();
makeOrder.makeOrderNum("a");
}
}, "at" + i);
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
MakeOrderNum makeOrder = new MakeOrderNum();
makeOrder.makeOrderNum("b");
}
}, "bt" + i);
t2.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}