1. Decode Twitter Snowflake ID in Java
Extract timestamp, worker ID, process ID, and sequence from a Twitter Snowflake ID.
import java.util.Date;
public class TwitterSnowflakeDecoder {
private static final long TWITTER_EPOCH = 1288834974657L;
public static void decode(long snowflakeId) {
// Extract timestamp (first 41 bits)
long timestamp = (snowflakeId >> 22) + TWITTER_EPOCH;
// Extract worker ID (next 5 bits)
long workerId = (snowflakeId >> 17) & 0x1F;
// Extract process ID (next 5 bits)
long processId = (snowflakeId >> 12) & 0x1F;
// Extract sequence (last 12 bits)
long sequence = snowflakeId & 0xFFF;
// Convert to Date
Date date = new Date(timestamp);
System.out.println("Snowflake ID: " + snowflakeId);
System.out.println("Timestamp: " + date);
System.out.println("Worker ID: " + workerId);
System.out.println("Process ID: " + processId);
System.out.println("Sequence: " + sequence);
}
public static void main(String[] args) {
decode(1382350606417817604L);
}
}
2. Generate Twitter Snowflake IDs in Java
Thread-safe Snowflake ID generator implementation.
public class TwitterSnowflakeGenerator {
private static final long TWITTER_EPOCH = 1288834974657L;
private static final long WORKER_ID_BITS = 5L;
private static final long PROCESS_ID_BITS = 5L;
private static final long SEQUENCE_BITS = 12L;
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
private static final long MAX_PROCESS_ID = ~(-1L << PROCESS_ID_BITS);
private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);
private final long workerId;
private final long processId;
private long sequence = 0L;
private long lastTimestamp = -1L;
public TwitterSnowflakeGenerator(long workerId, long processId) {
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException("Worker ID out of range");
}
if (processId > MAX_PROCESS_ID || processId < 0) {
throw new IllegalArgumentException("Process ID out of range");
}
this.workerId = workerId;
this.processId = processId;
}
public synchronized long nextId() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards");
}
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
// Sequence exhausted, wait for next millisecond
timestamp = waitNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// Combine all parts into Snowflake ID
return ((timestamp - TWITTER_EPOCH) << 22)
| (workerId << 17)
| (processId << 12)
| sequence;
}
private long waitNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
public static void main(String[] args) {
TwitterSnowflakeGenerator generator = new TwitterSnowflakeGenerator(1, 1);
// Generate 5 IDs
for (int i = 0; i < 5; i++) {
System.out.println("Generated ID: " + generator.nextId());
}
}
}
3. Complete Snowflake Utility Class
Production-ready utility class with both generation and decoding.
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class TwitterSnowflake {
private static final long TWITTER_EPOCH = 1288834974657L;
public static class SnowflakeInfo {
public final long id;
public final long timestamp;
public final int workerId;
public final int processId;
public final int sequence;
public SnowflakeInfo(long id, long timestamp, int workerId,
int processId, int sequence) {
this.id = id;
this.timestamp = timestamp;
this.workerId = workerId;
this.processId = processId;
this.sequence = sequence;
}
public String getFormattedDate() {
Instant instant = Instant.ofEpochMilli(timestamp);
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneId.systemDefault());
return formatter.format(instant);
}
@Override
public String toString() {
return String.format(
"SnowflakeInfo{id=%d, date=%s, worker=%d, process=%d, seq=%d}",
id, getFormattedDate(), workerId, processId, sequence
);
}
}
public static SnowflakeInfo decode(long snowflakeId) {
long timestamp = (snowflakeId >> 22) + TWITTER_EPOCH;
int workerId = (int)((snowflakeId >> 17) & 0x1F);
int processId = (int)((snowflakeId >> 12) & 0x1F);
int sequence = (int)(snowflakeId & 0xFFF);
return new SnowflakeInfo(snowflakeId, timestamp, workerId, processId, sequence);
}
public static void main(String[] args) {
// Example: Decode a Twitter ID
long tweetId = 1382350606417817604L;
SnowflakeInfo info = decode(tweetId);
System.out.println(info);
}
}