首页 > 编程语言 >Snowflake算法生成Id

Snowflake算法生成Id

时间:2024-01-15 20:23:38浏览次数:33  
标签:1L long Id Snowflake public 算法 private snowflake

网上大部分C#写的都有点乱糟糟,我简化了一下:

using System;

namespace xxx
{
    /// <summary>
    /// Id 生成类
    /// </summary>
    class Snowflake
    {
        private const string LOCK_OBJ = "76003AEB-E3F9-460A-BD31-D9AE9E7684C0";

        private const int MACHINE_BIT_SIZE = 10; // 机器编号长度10位
        private const int SEQUENCE_BIT_SIZE = 12; // 序号长度12位

        private static Snowflake _snowflake;

        private long _machineNumber; // 机器序号
        private long _timestamp; // 时间戳
        private long _sequence; // 序号

        private Snowflake() { }

        /// <summary>
        /// 设置机器序号
        /// </summary>
        public int MachineMumber
        {
            set { _machineNumber = value; }
        }

        /// <summary>
        /// 得到一个实例
        /// </summary>
        /// <returns></returns>
        public static Snowflake GetInstance()
        {
            if (_snowflake == null)
            {
                lock (LOCK_OBJ)
                {
                    if (_snowflake == null)
                    {
                        _snowflake = new Snowflake();
                    }
                }
            }
            return _snowflake;
        }

        /// <summary>
        /// 产生一个id,由时间戳、机器编码、顺序号组成
        /// </summary>
        /// <returns></returns>
        public long GenerateId(DateTime now)
        {
            lock (LOCK_OBJ)
            {
                if (_machineNumber > (-1L ^ -1L << MACHINE_BIT_SIZE))
                {
                    throw new ArgumentException("机器编号超出最大值");
                }

                long timestamp = GetTimestamp(now);
                if (timestamp < _timestamp)
                {
                    throw new ArgumentException("时间戳错误");
                }

                if (timestamp == _timestamp)
                {
                    _sequence++;
                    if (_sequence > (-1L ^ -1L << SEQUENCE_BIT_SIZE))
                    {
                        throw new ArgumentException("序号超出最大值");
                    }
                }
                else
                {
                    _sequence = 0;
                }

                long id = timestamp << (MACHINE_BIT_SIZE + SEQUENCE_BIT_SIZE) 
                    | _machineNumber << SEQUENCE_BIT_SIZE 
                    | _sequence;

                _timestamp = timestamp;

                return id;
            }
        }

        // 当前时间戳
        private long GetTimestamp(DateTime now)
        {
            return (long)(now - new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
        }
    }
}

调用:

namespace xxx
{
    public class IdGenerator
    {
        /// <summary>
        /// 生成Id
        /// </summary>
        /// <returns>id</returns>
        public static string GenerateId()
        {
            Snowflake sf = Snowflake.GetInstance();
            sf.MachineMumber = yourGetMachineFunction();
            long id = sf.GenerateId(yourGetTimestampFunction());
            return id.ToString();
        }
    }
}

标签:1L,long,Id,Snowflake,public,算法,private,snowflake
From: https://www.cnblogs.com/zzy0471/p/17966215

相关文章

  • LSP 网络劫持(Layered Service Provider Hijacking)
    LSP简介:分层服务提供商(LayeredServiceProvider,LSP)是一种可以扩展Winsock作为应用程序的Windows的网络套接字工具的机制。WinsockLSP可用于非常广泛的实用用途,包括Internet家长控制(parentalcontrol)和Web内容筛选。在以前版本的WindowsXP中,删除不正确的(也称......
  • Idea SpringBoot 子模块 加载不到该子模块根目录config下面的配置文件
    IdeaSpringBoot子模块加载不到该子模块根目录config下面的配置文件importorg.mybatis.spring.annotation.MapperScan;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframew......
  • LSP 网络劫持(Layered Service Provider Hijacking)
    LSP简介:分层服务提供商(LayeredServiceProvider,LSP)是一种可以扩展Winsock作为应用程序的Windows的网络套接字工具的机制。WinsockLSP可用于非常广泛的实用用途,包括Internet家长控制(parentalcontrol)和Web内容筛选。在以前版本的WindowsXP中,删除不正确的(也称......
  • width:100%与width:auto区别
    小知识width:100%与width:auto区别width:100%:子元素的content撑满父元素的content,如果子元素还有padding、border等属性,或者是在父元素上设置了边距和填充,都有可能会造成子元素区域溢出显示;width:auto:是子元素的content+padding+border+margin等撑满父元素的cont......
  • 聚类算法学习总结
    1.1聚类的定义聚类(Clustering)是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。也即聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。1.2聚类和分类的区别......
  • JQGrid自動翻頁
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width,init......
  • Androidmanifest文件加固和对抗
    前言恶意软件为了不让我们很容易反编译一个apk,会对androidmanifest文件进行魔改加固,本文探索androidmanifest加固的常见手法以及对抗方法。这里提供一个恶意样本的androidmanifest.xml文件,我们学完之后可以动手实践。1、Androidmanifest文件组成这里贴一张经典图,主要描述了andr......
  • 安装android Studio 以及flutter
    开发装备的环境配置java环境系统变量里面添加JAVA_HOME软后在path中添加java环境配置查看java是否安装成功 然后安装 系统变量添加 ANDROID_HOME  在path中添加 然后在path中添加flutter环境变量win+r/cmd ---flutterdoctor打开网址 https://......
  • 图像算法(掩膜)
    在图像处理中,掩膜(Mask)是一个用于指定图像中感兴趣区域的二进制图像或矩阵。掩膜通常用于选择、过滤或操作图像的特定区域。掩膜通常表示为一个二进制图像,其中白色像素表示感兴趣的区域,而黑色像素表示不感兴趣的区域。在计算机科学中,掩膜(mask)通常是一个二进制模式,用于对另一个数......
  • IDEA画图神器 PlantUML
    PlantUML是一款开源的UML图绘制工具,支持通过文本来生成图形,使用起来非常高效。可以支持时序图、类图、对象图、活动图、思维导图等图形的绘制。下面使用PlantUML来绘制一张流程图,可以实时预览,速度也很快!在线安装首先在IDEA的插件市场中搜索PlantUML,安装这个排名第一的插件;......