C#实现一个雪花算法
时间: 2023-06-29 09:09:59 浏览: 81
下面是一个简单的 C# 实现雪花算法的代码:
```csharp
public class SnowflakeIdGenerator
{
private const long Twepoch = 1288834974657L;
private const int WorkerIdBits = 5;
private const int DatacenterIdBits = 5;
private const int SequenceBits = 12;
private const long MaxWorkerId = -1L ^ (-1L << WorkerIdBits);
private const long MaxDatacenterId = -1L ^ (-1L << DatacenterIdBits);
private const int WorkerIdShift = SequenceBits;
private const int DatacenterIdShift = SequenceBits + WorkerIdBits;
private const int TimestampLeftShift = SequenceBits + WorkerIdBits + DatacenterIdBits;
private const long SequenceMask = -1L ^ (-1L << SequenceBits);
private readonly object _lock = new object();
private long _lastTimestamp = -1L;
private long _sequence = 0L;
public SnowflakeIdGenerator(long workerId, long datacenterId)
{
if (workerId > MaxWorkerId || workerId < 0)
{
throw new ArgumentException($"worker Id can't be greater than {MaxWorkerId} or less than 0");
}
if (datacenterId > MaxDatacenterId || datacenterId < 0)
{
throw new ArgumentException($"datacenter Id can't be greater than {MaxDatacenterId} or less than 0");
}
WorkerId = workerId;
DatacenterId = datacenterId;
}
public long WorkerId { get; }
public long DatacenterId { get; }
public long NextId()
{
lock (_lock)
{
var timestamp = TimeGen();
if (timestamp < _lastTimestamp)
{
throw new InvalidOperationException($"Clock moved backwards. Refusing to generate id for {_lastTimestamp - timestamp} milliseconds");
}
if (_lastTimestamp == timestamp)
{
_sequence = (_sequence + 1) & SequenceMask;
if (_sequence == 0)
{
timestamp = TilNextMillis(_lastTimestamp);
}
}
else
{
_sequence = 0;
}
_lastTimestamp = timestamp;
return ((timestamp - Twepoch) << TimestampLeftShift) |
(DatacenterId << DatacenterIdShift) |
(WorkerId << WorkerIdShift) |
_sequence;
}
}
private long TilNextMillis(long lastTimestamp)
{
var timestamp = TimeGen();
while (timestamp <= lastTimestamp)
{
timestamp = TimeGen();
}
return timestamp;
}
private static long TimeGen()
{
return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
}
}
```
使用示例:
```csharp
var generator = new SnowflakeIdGenerator(workerId: 1, datacenterId: 1);
var id = generator.NextId();
Console.WriteLine(id);
```
其中,`workerId` 和 `datacenterId` 分别表示工作机器 ID 和数据中心 ID,需要根据具体情况进行配置。`NextId` 方法用于生成下一个雪花算法的 ID。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)