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日

相关文章

  • C#中struct和class的区别详解

    C#中struct和class的区别 在C#中,struct和class是两种最常用的用户定义类型。虽然两者看起来很相似,但它们有一些关键的区别。本攻略将详细讲解C#中struct和class的区别。 声明语法的区别 声明语法是struct和class的首要区别。在C#中,使用struct关键字声明结构体,而使用class关键字声明类。下面是两种类型的声明语…

    C# 2023年5月15日
    00
  • 详解C# 中的正则表达式运用

    详解C#中的正则表达式运用 什么是正则表达式? 正则表达式(Regular Expression)是一种用来描述、匹配特定字符集合的字符串。一般用来做文本处理和字符串匹配,包括但不限于文本查找、替换、分割、提取等。 正则表达式的语法 具体的正则表达式语法非常复杂,这里只介绍C#的正则表达式语法常用的部分。 文本匹配 匹配单个字符:可以直接使用字符本身表示。例…

    C# 2023年6月8日
    00
  • .net泛型通用函数的特殊问题的解决方法

    .NET泛型通用函数的特殊问题的解决方法 问题描述 在使用.NET泛型通用函数时,偶尔会遇到类型推断错误和性能降低等问题,如何解决这些问题呢? 解决方法 1. 明确指定泛型类型 当类型推断错误导致编译器无法正确推断泛型函数的类型时,我们可以通过明确指定泛型类型来解决这个问题。示例如下: List<object> list = new List&l…

    C# 2023年5月14日
    00
  • C#编程实现Excel文档中搜索文本内容的方法及思路

    C#编程实现Excel文档中搜索文本内容的方法及思路 在 C# 编程中,实现搜索 Excel 文档中的文本内容是一个常见的需求。本文将介绍如何使用 C# 进行 Excel 文档的搜索文本内容,并附带两个示例说明。 思路 实现搜索 Excel 文档中的文本内容,可以采用以下步骤: 打开需要搜索的 Excel 文档。 遍历 Excel 文档中的所有单元格,查找包…

    C# 2023年6月8日
    00
  • .NET/C#如何使用反射注册事件详解

    要使用反射注册事件,可以遵循以下步骤: 步骤1:获取需要注册事件的对象类型 使用 typeof 或者 GetType() 方法获取需要注册事件的对象类型。例如,下面的示例代码获取了一个名为 MyClass 的类的类型: Type type = typeof(MyClass); 步骤2:获取事件的 MethodInfo 使用 GetEvent 方法获取事件的 …

    C# 2023年5月15日
    00
  • C# JWT权限验证的实现

    让我给您详细讲解关于“C# JWT权限验证的实现”的完整攻略。在此过程中,我将通过以下几个步骤来完成: 安装依赖项 编写授权逻辑代码 创建JWT 验证JWT 以下是每个步骤的详细说明和相应的代码示例: 1. 安装依赖项 在开始之前,您需要安装下列依赖项: Microsoft.AspNetCore.Authentication.JwtBearer:用于令牌验证…

    C# 2023年6月1日
    00
  • .NET Core读取配置文件的方法

    .NET Core读取配置文件的方法 在.NET Core应用程序中,读取配置文件是一项非常重要的任务。配置文件可以包含应用程序的各种设置,如数据库连接字符串、日志级别、缓存设置等。在本攻略中,我们将介绍.NET Core读取配置文件的方法,并提供两个示例说明。 1. 配置文件的格式 在.NET Core应用程序中,配置文件的格式可以是JSON、XML、IN…

    C# 2023年5月16日
    00
  • 用C#编写ActiveX控件(二)

    这里是详细讲解“用C#编写ActiveX控件(二)”的完整攻略。 1. 什么是ActiveX控件 ActiveX控件是一种运行在Windows操作系统上的可重用组件技术,它可以通过Web页面在Internet上进行传播使用,早期广泛应用于Internet Explorer中的插件。ActiveX控件的编写可以使用多种语言实现,如C++、VB、C#等。 2. …

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