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# 类型转换

    下面是关于”c#类型转换”的完整攻略。 什么是类型转换? C#的类型转换是将一种数据类型的变量转换为另一种数据类型的变量。在C#中,类型转换有两种形式:隐式转换和显式转换。 隐式转换(Implicit Cast):是从小的数据类型向大的数据类型转换的,不需要进行任何特殊处理。C#程序员无需编写任何代码来实现隐式类型转换,开发环境会自动帮助我们实现。 显式转换…

    C# 2023年5月31日
    00
  • Redis数据库基础与ASP.NET Core缓存实现

    Redis数据库基础与ASP.NET Core缓存实现 Redis是一种高性能的键值存储数据库,常用于缓存、消息队列、会话管理等场景。本攻略将介绍Redis数据库的基础知识,并演示如何在ASP.NET Core应用程序中使用Redis作为缓存。 Redis数据库基础 安装Redis 在使用Redis之前,需要先安装Redis。可以使用以下命令在Ubuntu上…

    C# 2023年5月17日
    00
  • C#递归算法和排列算法

    C#递归算法和排列算法 什么是递归算法? 递归算法是一种在函数中调用自身的算法。具有以下特征:- 一个问题可以被分解成几个相同的子问题;- 分解出来的子问题和原问题的解法方式一样;- 递归算法必须要有终止条件。 递归算法在程序设计中应用非常广泛,尤其在树形数据结构的遍历、图形搜索、分治法等方面都有很好的应用。 递归算法示例 下面是一个实现阶乘计算的递归算法:…

    C# 2023年6月7日
    00
  • C#中DataTable 转实体实例详解

    下面是关于“C#中DataTable 转实体实例详解”的完整攻略: 1. 为什么需要将DataTable转为实体实例 在C#中,DataTable是一种非常常见的数据类型。在我们进行数据查询、统计和展示时,经常使用DataTable来存储数据。而在使用DataTable时,我们通常需要将DataTable中的数据转化为我们自定义的实体类型,利用实体的属性和方…

    C# 2023年5月31日
    00
  • abp(net core)+easyui+efcore实现仓储管理系统——模块管理升级之上(六十一)

     Abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+easyui+efcore实现仓储管理系统——解决方案介绍(二) abp(net core)+easyui+efcore实现仓储管理系统——领域层创建实体(三…

    C# 2023年4月17日
    00
  • netcore mvc efcore 简单框架搭建+增删改查

    该例子使用的数据库是 mysql;.net core 框架,版本(sdk)是3.1。 一:创建个net core 版本的mvc  目标框架选   net core3.1  二:项目创建好之后  先安装今天要使用到的nuget包(下载的包最好也是3.1版本的) Microsoft.EntityFrameworkCore; Microsoft.EntityFra…

    C# 2023年4月22日
    00
  • ASP.net Forms验证Demo

    下面是关于“ASP.net Forms验证Demo”的完整攻略: 1. 什么是ASP.net Forms验证Demo ASP.net Forms验证Demo是一种在ASP.net网站中使用的验证方式,它可以验证用户输入的表单数据是否合法。这种验证方式可以确保用户输入的数据符合规定的格式和内容,同时也可以保证网站数据的安全性。 2. 如何创建ASP.net F…

    C# 2023年5月31日
    00
  • SQL Server 2008 新特性 总结复习(一)

    SQL Server 2008 新特性 总结复习(一) SQL Server 2008 是微软公司开发的一款数据库管理系统软件,它具有很多新特性,本文将会对其中一些新特性进行详细讲解。 1. 影响行的Trigger 在 SQL Server 2008 中,Trigger 变得更加强大了,它可以使用 inserted 和 deleted 表来访问触发器所在表中…

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