雪花算法

 

.net core 雪花算法
雪花算法(Snowflake)是一种用于生成唯一ID的算法,适用于分布式系统。在.NET Core中,你可以使用以下代码实现雪花算法生成ID:

public class SnowflakeIdGenerator
{
    private const ulong Twepoch = 1288834974657; // 起始时间 (2010-11-04 09:42:54.657)
    private const int WorkerIdBits = 5; // 机器ID所占的位数
    private const int DatacenterIdBits = 5; // 数据中心ID所占的位数
    private const int SequenceBits = 12; // 序列所占的位数
 
    private const int WorkerIdShift = SequenceBits; // 机器ID左移位数,10位
    private const int DatacenterIdShift = SequenceBits + WorkerIdBits; // 数据中心ID左移位数,15位
    private const ulong TimestampLeftShift = SequenceBits + WorkerIdBits + DatacenterIdBits; // 时间戳左移位数,22位
 
    private const ulong SequenceMask = -1 ^ (-1 << SequenceBits); // 生成序列的掩码,0000 0000 0000 0000 0000 0000 1111 1111 1111
 
    private ulong _lastTimestamp = 0;
    private ulong _sequence = 0;
 
    private readonly object _lock = new object();
    private readonly ulong _workerId; // 机器ID
    private readonly ulong _datacenterId; // 数据中心ID
 
    public SnowflakeIdGenerator(ulong workerId, ulong datacenterId)
    {
        _workerId = workerId;
        _datacenterId = datacenterId;
    }
 
    public ulong NextId()
    {
        lock (_lock)
        {
            ulong timestamp = TimeGen();
 
            if (_lastTimestamp > timestamp)
            {
                throw new Exception($"Clock moved backwards, refusing to generate id for {_lastTimestamp - timestamp} milliseconds");
            }
 
            if (_lastTimestamp == timestamp)
            {
                _sequence = (_sequence + 1) & SequenceMask;
                if (_sequence == 0)
                {
                    timestamp = TillNextMillis(_lastTimestamp);
                }
            }
            else
            {
                _sequence = 0;
            }
 
            _lastTimestamp = timestamp;
 
            ulong id = ((timestamp - Twepoch) << TimestampLeftShift) |
                       (_datacenterId << DatacenterIdShift) |
                       (_workerId << WorkerIdShift) | _sequence;
 
            return id;
        }
    }
 
    private ulong TimeGen()
    {
        return (ulong)(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - Twepoch);
    }
 
    private ulong TillNextMillis(ulong lastTimestamp)
    {
        ulong timestamp = TimeGen();
        while (timestamp <= lastTimestamp)
        {
            timestamp = TimeGen();
        }
        return timestamp;
    }
}
使用方法:

var idGenerator = new SnowflakeIdGenerator(workerId: 1, datacenterId: 1); // 设置机器ID和数据中心ID
ulong id = idGenerator.NextId(); // 生成新的ID
请根据实际情况设置workerId和datacenterId。这个实现是线程安全的,可以在分布式系统中使用。

  

posted on 2024-07-27 22:33  是水饺不是水饺  阅读(26)  评论(0)    收藏  举报

导航