C# Guid长度雪花简单生成器的示例代码

下面是针对如何编写C# Guid长度的雪花简单生成器的攻略。

1. 为何选择C# Guid

C# Guid(全称为全球唯一标识符)是一个128位的数字,由字母和数字构成,它具备全局唯一性,即全球内任意两个Guid的相同概率是非常低的。因此,我们可以利用Guid生成唯一字符串,例如用户ID、订单编号等。

2. 如何生成雪花ID

雪花ID是一种Twitter开源的生成分布式唯一ID的算法,可以在分布式系统中生成全局唯一ID,其算法是基于时间戳实现。每次生成ID时,将当前时间戳拼接其它固定的信息(如机器IP、PID等),再通过Hash等算法进行混淆,最终生成一个64位长整数。

将雪花ID生成的64位长整数转化为字符串,再以Guid的方式进行排版,即可生成所需的雪花ID。

下面是示例代码:

using System;
using System.Security.Cryptography;
using System.Text;

namespace Snowflake
{
    class Program
    {
        static void Main(string[] args)
        {
            Snowflake snowflake = new Snowflake(0, 0);
            Console.WriteLine(GuidFromSnowflake(snowflake.NextId()));
        }

        public static Guid GuidFromSnowflake(long id)
        {
            return new Guid(
                BitConverter.GetBytes(id >> 48 & 0xFFFF),
                BitConverter.GetBytes(id >> 32 & 0xFFFF),
                BitConverter.GetBytes(id >> 16 & 0xFFFF),
                BitConverter.GetBytes(id & 0xFFFF));
        }
    }

    public class Snowflake
    {
        private long workerId;
        private long datacenterId;
        private long sequence = 0L;
        private long lastTimestamp = -1L;
        private static long twepoch = 1288834974657L;

        public Snowflake(long workerId, long datacenterId)
        {
            if (workerId > maxWorkerId || workerId < 0)
            {
                throw new Exception("worker Id can't be greater than " + maxWorkerId + " or less than 0");
            }
            if (datacenterId > maxDatacenterId || datacenterId < 0)
            {
                throw new Exception("datacenter Id can't be greater than " + maxDatacenterId + " or less than 0");
            }
            this.workerId = workerId;
            this.datacenterId = datacenterId;
        }

        private static long workerIdBits = 5L;
        private static long datacenterIdBits = 5L;
        private static long maxWorkerId = -1L ^ -1L << (int)workerIdBits;
        private static long maxDatacenterId = -1L ^ -1L << (int)datacenterIdBits;
        private static long sequenceBits = 12L;
        private static long workerIdShift = sequenceBits;
        private static long datacenterIdShift = sequenceBits + workerIdBits;
        private static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
        private static long sequenceMask = -1L ^ -1L << (int)sequenceBits;

        private static long GetTimestamp()
        {
            return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
        }

        public long NextId()
        {
            lock (this)
            {
                long timestamp = GetTimestamp();
                if (timestamp < lastTimestamp)
                {
                    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 = TilNextMillis(lastTimestamp);
                    }
                }
                else
                {
                    sequence = 0L;
                }
                lastTimestamp = timestamp;
                return (timestamp - twepoch) << (int)timestampLeftShift |
                          datacenterId << (int)datacenterIdShift |
                          workerId << (int)workerIdShift |
                          sequence;
            }
        }

        private long TilNextMillis(long lastTimestamp)
        {
            long timestamp = GetTimestamp();
            while (timestamp <= lastTimestamp)
            {
                timestamp = GetTimestamp();
            }
            return timestamp;
        }
    }
}

上述代码通过 Snowflake 算法实现了雪花ID的生成。我们创建了一个 Snowflake 的类,构造函数接收两个参数:workerId,datacenterId。在 NextId() 方法内部,我们通过 lock 机制对 ID 进行互斥操作,确保在多线程环境下不会生成重复的ID。

3. 示例说明

示例 1:

我们可以根据上述代码编写一个控制台应用程序,用于生成雪花ID,并输出其所对应的Guid。

在控制台中输入以下命令:

Snowflake snowflake = new Snowflake(0, 0);
Console.WriteLine(GuidFromSnowflake(snowflake.NextId()));

运行控制台应用程序,可看到所生成的雪花ID的Guid。

示例 2:

将上述代码封装成一个简单的 Web API,通过 HTTP 请求访问,返回所生成的雪花ID的Guid。

使用 Visual Studio 创建一个 ASP.NET Core Web API 应用程序,并在控制器类中接收 HTTP 请求。示例如下:

using System;
using Microsoft.AspNetCore.Mvc;

namespace SnowflakeWebAPI.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class SnowflakeController : ControllerBase
    {
        private Snowflake snowflake = new Snowflake(0, 0);

        [HttpGet]
        public IActionResult Get()
        {
            return Ok(new {
                guid = GuidFromSnowflake(snowflake.NextId())
            });
        }

        private static Guid GuidFromSnowflake(long id)
        {
            return new Guid(
                BitConverter.GetBytes(id >> 48 & 0xFFFF),
                BitConverter.GetBytes(id >> 32 & 0xFFFF),
                BitConverter.GetBytes(id >> 16 & 0xFFFF),
                BitConverter.GetBytes(id & 0xFFFF));
        }

        class Snowflake
        {
            // ...
        }
    }
}

在浏览器或任意 HTTP 客户端工具中输入 URL:http://localhost:5000/snowflake,即可看到所生成的雪花ID的Guid。

总结

在本篇攻略中,我们详细讲解了如何使用 C# Guid 实现雪花ID的生成器,并提供了两条示例说明。这个生成器是在分布式系统中生成全局唯一ID的理想选择。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# Guid长度雪花简单生成器的示例代码 - Python技术站

(0)
上一篇 2023年6月1日
下一篇 2023年6月1日

相关文章

  • Unity 使用tiledmap解析地图的详细过程

    下面是Unity使用Tiled Map解析地图的详细过程。 什么是Tiled Map Tiled Map是一个开源的地图编辑器,可以用来创建2D地图,支持多种地图格式,并可以导出为多种数据格式,如XML、JSON等。Unity可以使用Tiled Map导出的地图数据文件解析出游戏世界中的2D地图。 Unity如何使用Tiled Map解析地图 Unity可以…

    C# 2023年5月31日
    00
  • .NET 6实现滑动验证码的示例详解

    以下是关于“.NET6实现滑动验证码的示例详解”的完整攻略: 1. 什么是滑动验证码? 滑动验证码是一种常见的验证码形式,它要求用户在一个滑块上滑动,以证明他们是真正的人类用户,而不是机器人或恶意软件。 2. 如何使用.NET6实现滑动验证码? 在.NET6中,可以使用ASP.NET Core MVC和JavaScript来实现滑动验证码。可以按照以下步骤操…

    C# 2023年5月12日
    00
  • Unity中Instantiate实例化物体卡顿问题的解决

    关于Unity中Instantiate实例化物体卡顿问题的解决,我整理了以下攻略: Unity中Instantiate实例化物体卡顿问题的解决 问题描述 在Unity开发过程中,使用Instantiate()函数实例化物体时,会出现卡顿现象,特别是当要大量实例化物体时,卡顿现象会更加明显。 解决方法 方法一:使用对象池 使用对象池是一种常见的解决Instan…

    C# 2023年6月3日
    00
  • C# Winform 调用系统接口操作 INI 配置文件的代码

    关于C# Winform调用系统接口操作INI配置文件的代码,下面是详细的攻略: 1. 什么是INI文件 INI文件是一种配置文件格式,全称叫做Initial file,是一种比较老式的配置文件格式。它的结构非常简单,通常包含了若干个节(section)和各个节下的键值对(key-value pair)。INI文件的格式如下: [section1] key1…

    C# 2023年6月7日
    00
  • C#使用SqlDataAdapter对象获取数据的方法

    下面详细讲解一下“C#使用SqlDataAdapter对象获取数据的方法”的完整攻略: 1. 准备工作 在使用SqlDataAdapter对象获取数据之前,需要先引用System.Data.SqlClient库。可以通过在程序代码中添加以下语句实现: using System.Data.SqlClient; 同时需要准备好连接数据库所需的参数,例如服务器名称…

    C# 2023年5月31日
    00
  • Win11提示powershell找不到mscoree.dll咋办? 错误代码0xc0000135解决办法

    如果在Windows 11中使用PowerShell时出现“找不到mscoree.dll”错误,错误代码为0xc0000135,可以尝试以下解决办法: 1. 重新安装.NET Framework mscoree.dll是.NET Framework的一部分,如果该文件丢失或损坏,可能会导致PowerShell无法正常工作。因此,可以尝试重新安装.NET Fr…

    C# 2023年5月15日
    00
  • C#中序列化实现深拷贝,实现DataGridView初始化刷新的方法

    下面是关于“C#中序列化实现深拷贝,实现DataGridView初始化刷新的方法”的完整攻略,包含两个示例。 1. C#中序列化实现深拷贝 在C#中,可以使用序列化实现深拷贝。以下是一个示例: public static T DeepCopy<T>(T obj) { using (MemoryStream stream = new MemoryS…

    C# 2023年5月15日
    00
  • C#修改IIS站点framework版本号的方法

    C#修改IIS站点framework版本号的方法 前言 在ASP.NET应用程序中,我们通常需要设置正确的.NET Framework版本。如果您使用IIS作为Web服务器,您可能需要在站点或应用程序池级别设置.NET Framework版本。当您升级服务器上的.NET Framework时,您还需要修改站点或应用程序池的.NET Framework版本以确…

    C# 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部