1. Decode Twitter Snowflake ID in C#
Extract timestamp, worker ID, process ID, and sequence from a Twitter Snowflake ID.
using System;
public class TwitterSnowflakeDecoder
{
private const 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 DateTime
DateTimeOffset date = DateTimeOffset.FromUnixTimeMilliseconds(timestamp);
Console.WriteLine($"Snowflake ID: {snowflakeId}");
Console.WriteLine($"Timestamp: {date}");
Console.WriteLine($"Worker ID: {workerId}");
Console.WriteLine($"Process ID: {processId}");
Console.WriteLine($"Sequence: {sequence}");
}
static void Main(string[] args)
{
Decode(1382350606417817604L);
}
}
2. Generate Twitter Snowflake IDs in C#
Thread-safe Snowflake ID generator implementation.
using System;
using System.Threading;
public class TwitterSnowflakeGenerator
{
private const long TWITTER_EPOCH = 1288834974657L;
private const long WORKER_ID_BITS = 5L;
private const long PROCESS_ID_BITS = 5L;
private const long SEQUENCE_BITS = 12L;
private const long MAX_WORKER_ID = ~(-1L << (int)WORKER_ID_BITS);
private const long MAX_PROCESS_ID = ~(-1L << (int)PROCESS_ID_BITS);
private const long MAX_SEQUENCE = ~(-1L << (int)SEQUENCE_BITS);
private readonly long _workerId;
private readonly long _processId;
private long _sequence = 0L;
private long _lastTimestamp = -1L;
private readonly object _lock = new object();
public TwitterSnowflakeGenerator(long workerId, long processId)
{
if (workerId > MAX_WORKER_ID || workerId < 0)
throw new ArgumentException("Worker ID out of range");
if (processId > MAX_PROCESS_ID || processId < 0)
throw new ArgumentException("Process ID out of range");
_workerId = workerId;
_processId = processId;
}
public long NextId()
{
lock (_lock)
{
long timestamp = GetCurrentTimestamp();
if (timestamp < _lastTimestamp)
throw new InvalidOperationException("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 GetCurrentTimestamp()
{
return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}
private long WaitNextMillis(long lastTimestamp)
{
long timestamp = GetCurrentTimestamp();
while (timestamp <= lastTimestamp)
{
Thread.Sleep(1);
timestamp = GetCurrentTimestamp();
}
return timestamp;
}
static void Main(string[] args)
{
var generator = new TwitterSnowflakeGenerator(1, 1);
// Generate 5 IDs
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"Generated ID: {generator.NextId()}");
}
}
}
3. Complete Snowflake Utility Class
Production-ready utility class with both generation and decoding.
using System;
public class TwitterSnowflake
{
private const long TWITTER_EPOCH = 1288834974657L;
public class SnowflakeInfo
{
public long Id { get; set; }
public long Timestamp { get; set; }
public int WorkerId { get; set; }
public int ProcessId { get; set; }
public int Sequence { get; set; }
public DateTimeOffset Date =>
DateTimeOffset.FromUnixTimeMilliseconds(Timestamp);
public string FormattedDate =>
Date.ToString("yyyy-MM-dd HH:mm:ss");
public override string ToString()
{
return $"SnowflakeInfo {{ Id={Id}, Date={FormattedDate}, " +
$"Worker={WorkerId}, Process={ProcessId}, Seq={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
{
Id = snowflakeId,
Timestamp = timestamp,
WorkerId = workerId,
ProcessId = processId,
Sequence = sequence
};
}
static void Main(string[] args)
{
// Example: Decode a Twitter ID
long tweetId = 1382350606417817604L;
var info = Decode(tweetId);
Console.WriteLine(info);
}
}