Java生成短ID 简介 在开发Java应用程序时,经常会遇到需要生成唯一标识符的情况。通常,我们会使用UUID(Universally Unique Identifier)来生成唯一标识符。然而,UUID生成的标识符太长了,不
          Java生成短ID
简介
在开发Java应用程序时,经常会遇到需要生成唯一标识符的情况。通常,我们会使用UUID(Universally Unique Identifier)来生成唯一标识符。然而,UUID生成的标识符太长了,不适合在一些特定场景中使用,比如URL缩短、短信验证码等。为了解决这个问题,我们可以使用一些算法来生成短ID。
本文将介绍一个常用的算法——雪花算法(Snowflake Algorithm),它可以生成一个长度较短的唯一标识符。
雪花算法
雪花算法是Twitter开源的一个算法,用于生成全局唯一的ID。它的原理非常简单,可以分为以下几个部分:
- 时间戳(41位):记录生成ID的时间戳,精确到毫秒级别。
 - 机器ID(10位):记录机器的唯一标识,可以手动指定或从机器的网卡中获取。
 - 序列号(12位):记录每个时间戳下生成的序列号,从0开始递增。
 
由于每个部分的位数是固定的,所以我们可以根据时间戳、机器ID和序列号生成一个64位的ID。由于时间戳占据了大部分的位数,所以生成的ID是趋势递增的,保证了生成的ID的有序性。
下面是一个使用Java实现雪花算法的示例代码:
public class SnowflakeIdGenerator {
    private static final long EPOCH = 1609459200000L;  // 2021-01-01 00:00:00
    private static final long MACHINE_ID_BITS = 10L;
    private static final long SEQUENCE_BITS = 12L;
    private static final long MAX_MACHINE_ID = (1L << MACHINE_ID_BITS) - 1L;
    private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1L;
    private long machineId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;
    public SnowflakeIdGenerator(long machineId) {
        if (machineId < 0 || machineId > MAX_MACHINE_ID) {
            throw new IllegalArgumentException("Invalid machine ID");
        }
        this.machineId = machineId;
    }
    public synchronized long generateId() {
        long timestamp = System.currentTimeMillis();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards");
        }
        if (timestamp == lastTimestamp) {
            sequence = (sequence + 1) & MAX_SEQUENCE;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }
        lastTimestamp = timestamp;
        return ((timestamp - EPOCH) << (MACHINE_ID_BITS + SEQUENCE_BITS))
                | (machineId << SEQUENCE_BITS)
                | sequence;
    }
    private long tilNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }
}
状态图
下面是雪花算法的状态图,使用mermaid语法绘制:
stateDiagram-v2
  [*] --> Idle
  Idle --> GeneratingId : generateId()
  GeneratingId --> Idle : ID generated
旅行图
下面是雪花算法的旅行图,使用mermaid语法绘制:
journey
  title Snowflake Algorithm Journey
  section Initialize
    [*] --> CheckMachineId : Initialize
    CheckMachineId --> [*] : Invalid machine ID
    CheckMachineId --> SetMachineId : Valid machine ID
  section Generate ID
    SetMachineId --> Idle : Start
    Idle --> GenerateId : generateId() called
    GenerateId --> Idle : ID generated
  section Handle Clock Backwards
    GenerateId --> ClockBackwards : Clock moved backwards
    ClockBackwards --> GenerateId : Retry
  section End
    GenerateId --> [*] : Stop
示例
下面是一个使用雪花算法生成短ID的示例:
public class ShortIdGeneratorExample {
    public static void main(String[] args) {
        SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1L);
        long id = idGenerator.generateId();
        String shortId = toShortId(id);
        System.out.println("Generated ID: " +
            
        
        
        
 