C# 雪花算法

https://blog.csdn.net/weixin_48916144/article/details/147990723

https://www.cnblogs.com/sexintercourse/p/18824051

public class SnowflakeIdGenerator
{
    // 雪花算法的各个参数
    private static readonly long Epoch = new DateTime(2022, 1, 1).Ticks / 10000;  // 设置纪元时间(单位:毫秒)
    private static readonly int MachineIdBits = 10;  // 机器ID部分占用的位数
    private static readonly int SequenceBits = 12;   // 序列号部分占用的位数

    private static readonly long MaxMachineId = -1L ^ (-1L << MachineIdBits);  // 最大机器ID(1023)
    private static readonly long SequenceMask = -1L ^ (-1L << SequenceBits);   // 最大序列号(4095)

    private long lastTimestamp = -1L;  // 上次生成ID的时间戳
    private long machineId;            // 机器ID
    private long sequence = 0L;        // 序列号

    private readonly object lockObject = new object();

    // 构造函数:传入机器ID
    public SnowflakeIdGenerator(long machineId)
    {
        if (machineId > MaxMachineId || machineId < 0)
        {
            throw new ArgumentException($"Machine ID should be between 0 and {MaxMachineId}");
        }

        this.machineId = machineId;
    }

    // 生成下一个唯一的ID
    public long NextId()
    {
        lock (lockObject)
        {
            long timestamp = GetCurrentTimestamp();

            if (timestamp == lastTimestamp)
            {
                // 同一毫秒内,序列号加1
                sequence = (sequence + 1) & SequenceMask;
                if (sequence == 0)
                {
                    // 如果序列号溢出,等待下一毫秒
                    timestamp = WaitNextMillis(lastTimestamp);
                }
            }
            else
            {
                sequence = 0;
            }

            lastTimestamp = timestamp;

            // 组合成64位的ID
            return (timestamp - Epoch) << (MachineIdBits + SequenceBits)  // 时间戳部分
                    | (machineId << SequenceBits)                        // 机器ID部分
                    | sequence;                                          // 序列号部分
        }
    }

    // 获取当前时间戳(毫秒)
    private long GetCurrentTimestamp()
    {
        return DateTime.UtcNow.Ticks / 10000 - Epoch;  // 获取当前时间的毫秒数
    }

    // 等待下一毫秒
    private long WaitNextMillis(long lastTimestamp)
    {
        long timestamp = GetCurrentTimestamp();
        while (timestamp <= lastTimestamp)
        {
            timestamp = GetCurrentTimestamp();
        }
        return timestamp;
    }
}

原文出处:/show_1GW1GMCna6oR.html