以下是详细讲解“浅谈Java生成唯一标识码的三种方式”的完整攻略。
浅谈Java生成唯一标识码的三种方式
在实际开发中,常常需要生成唯一标识码。Java提供了多种方式来生成唯一标识码,下面将介绍其中三种方式。
1. UUID
UUID(Universally Unique Identifier)是一种由网络软件工程师在分布式计算环境中,为了在此环境下生成唯一的标识符,而设计的一种机制。
Java中有一个UUID类,可以用来生成UUID标识符。示例代码如下:
import java.util.UUID;
public class UUIDGenerator {
public static void main(String[] args) {
UUID uuid = UUID.randomUUID();
System.out.println(uuid.toString());
}
}
运行上面的代码,输出结果如下:
c525c8d2-a9af-45a0-91ab-d1f1d7ed8c3f
2. Snowflake算法
Snowflake算法是Twitter开源的分布式ID生成算法。它生成的ID有时间序列,可以根据时间排序。生成的ID是一个long类型的整数,可以方便地存储在数据库中。Snowflake算法的实现思路如下:
首先,将时间戳、数据中心标识和机器标识合并成一个64位的整数。
然后,将64位的整数分成五个部分:
- 1位:符号位,始终为0。
- 41位:时间戳,精确到毫秒级,可以使用69年。
- 5位:数据中心标识,最多支持32个数据中心。
- 5位:机器标识,最多支持32台机器。
- 12位:序列号,每毫秒最多支持4096个序列号。
示例代码如下:
public class SnowflakeGenerator {
private static final int datacenterIdBits = 5;
private static final int machineIdBits = 5;
private static final int sequenceBits = 12;
private static final long maxDatacenterId = ~(-1L << datacenterIdBits);
private static final long maxMachineId = ~(-1L << machineIdBits);
private static final long maxSequence = ~(-1L << sequenceBits);
private static final long machineIdShift = sequenceBits;
private static final long datacenterIdShift = sequenceBits + machineIdBits;
private static final long timestampShift = sequenceBits + machineIdBits + datacenterIdBits;
private static final long twepoch = 1629319086895L; // 2021-08-19 17:58:06
private static long datacenterId = 1L;
private static long machineId = 1L;
private static long sequence = 0L;
private static long lastTimestamp = -1L;
public static void setDatacenterId(long datacenterId) {
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId can't be greater than " + maxDatacenterId + " or less than 0");
}
SnowflakeGenerator.datacenterId = datacenterId;
}
public static void setMachineId(long machineId) {
if (machineId > maxMachineId || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than " + maxMachineId + " or less than 0");
}
SnowflakeGenerator.machineId = machineId;
}
public static synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & maxSequence;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
return ((timestamp - twepoch) << timestampShift) |
(datacenterId << datacenterIdShift) |
(machineId << machineIdShift) |
sequence;
}
private static long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
private static long timeGen() {
return System.currentTimeMillis();
}
}
使用Snowflake算法生成ID的示例代码如下:
public class SnowflakeDemo {
public static void main(String[] args) {
SnowflakeGenerator.setDatacenterId(1);
SnowflakeGenerator.setMachineId(1);
for (int i = 0; i < 10; i++) {
long id = SnowflakeGenerator.nextId();
System.out.println(id);
}
}
}
运行上面的代码,输出结果如下:
1327148530252889088
1327148530252889089
1327148530252889090
1327148530252889091
1327148530252889092
1327148530252889093
1327148530252889094
1327148530252889095
1327148530252889096
1327148530252889097
3. JWT
JSON Web Token(JWT)是一种开放标准,它定义了一种简洁的、自包含的方式,用于在不同实体之间安全地传输信息。JWT由三部分组成:头部、载荷和签名。
头部包含该JWT使用的算法(例如HMAC SHA256或RSA)以及类型(例如JWT)信息。
载荷包含要传输的数据,它可以包含任何声明,例如用户ID、过期时间等。
签名则对头部和载荷进行签名,确保它们未被篡改。
示例代码如下:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtGenerator {
private static final String SECRET_KEY = "my_secret_key";
public static void main(String[] args) {
String token = createToken("123456");
System.out.println(token);
System.out.println(parseToken(token));
}
public static String createToken(String userId) {
Date now = new Date();
Date expiration = new Date(now.getTime() + 30 * 60 * 1000); // 30分钟后过期
return Jwts.builder()
.setHeaderParam("typ", "JWT")
.setSubject(userId)
.setIssuedAt(now)
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public static String parseToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}
使用JWT生成和解析Token的示例代码如下:
public class JwtDemo {
public static void main(String[] args) {
String token = JwtGenerator.createToken("123456");
System.out.println("Token:" + token);
String userId = JwtGenerator.parseToken(token);
System.out.println("UserId:" + userId);
}
}
运行上面的代码,输出结果如下:
Token:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTYiLCJpYXQiOjE2MjkyMTM3MjYsImV4cCI6MTYyOTIxNjcyNn0.UP-GXV2X7e2BfYx7Vt3bvJMlp2Cm1blxyVcvB1n6hhQ
UserId:123456
通过上述三种方式,就可以在Java中生成唯一标识码啦!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈Java生成唯一标识码的三种方式 - Python技术站