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# 调用命令行执行Cmd命令的操作

    C# 调用命令行执行 Cmd 命令可以通过使用 Process 类实现。下面是具体步骤: 1. 引用命名空间 在 C# 中使用 Process 类需要引用 System.Diagnostics 命名空间,因此需要在文件头部添加以下代码: using System.Diagnostics; 2. 创建 Process 对象 创建一个 Process 对象,可以…

    C# 2023年6月7日
    00
  • C#基础知识之字符串和正则表达式

    C#基础知识之字符串和正则表达式 一、字符串 1. 字符串的定义 在 C# 中,字符串是一个不可变的对象,表示文字和其他字符序列。C# 中的字符串对象是 System.String 类型的实例。创建字符串即是创建 String 对象,并使用双引号或 @-引号字符串来表示字符串值。如: string str1 = "Hello world!&quot…

    C# 2023年6月1日
    00
  • c#使用热键实现程序窗口隐藏示例

    让我来详细讲解一下C#使用热键实现程序窗口隐藏的攻略。 步骤一:注册系统热键 在C#中使用热键需要注册全局热键,这可以通过调用Windows API函数实现。以下是一些示例代码,用于注册和注销全局热键: using System.Runtime.InteropServices; public class GlobalHotkey { [DllImport(&…

    C# 2023年6月7日
    00
  • log4net配置和使用方法分享

    下面是“log4net配置和使用方法分享”的完整攻略。 1. 简介 log4net是一个强大的.NET日志记录库,它允许您记录到多个输出目标,包括文件、控制台、数据库、电子邮件和其他自定义输出目标。log4net是Apache Software Foundation的一个项目,它和另一个流行的Java日志记录库log4j很相似。在本文中,我们将学习如何配置和…

    C# 2023年5月31日
    00
  • C#如何操作Excel数据透视表

    C#操作Excel数据透视表需要使用Microsoft.Office.Interop.Excel命名空间,以下是详细攻略: 安装Microsoft Excel:在操作Excel之前,必须安装Microsoft Excel软件。如果已经安装则可以跳过该步骤。 添加引用:右击项目,选择“添加”->“引用”,在弹出的对话框中选择“COM”标签页,找到Micr…

    C# 2023年6月6日
    00
  • Bin 和 App_Code 文件夹介绍

    首先,在ASP.NET的网站解决方案中,Bin和App_Code文件夹都是非常重要的文件夹,它们在网站的应用程序编译和代码管理中起到了非常重要的作用。下面我们来看一下这两个文件夹的介绍及其用途。 Bin文件夹介绍: Bin文件夹是ASP.NET网站应用程序中的一个特殊目录,其中存放了所有编译后的程序集,这些程序集会被加载到ASP.NET应用程序的AppDom…

    C# 2023年6月7日
    00
  • C#开发windows服务实现自动从FTP服务器下载文件

    下面是详细说明: 一、前置条件 电脑上安装Visual Studio(建议版本大于2015)。 确保安装了.NET Framework 4及以上版本。 需要有一个FTP账号和FTP服务器。 二、创建Windows服务应用程序 1. 打开Visual Studio,点击“新建项目”; 2. 选择“Windows服务”类型,并起名为“FTPDownloadSer…

    C# 2023年6月1日
    00
  • Netcore磊科路由器无线MAC地址过滤图解教程

    Netcore磊科路由器无线MAC地址过滤图解教程如下: 步骤一:登录路由器 首先,需要登录到 Netcore 磊科路由器的管理界面。在浏览器中输入路由器的 IP 地址,然后输入用户名和密码进行登录。 步骤二:进入无线设置页面 在登录成功后,进入路由器的无线设置页面。在页面中找到“MAC地址过滤”选项,并点击进入。 步骤三:启用MAC地址过滤 在“MAC地址…

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