You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
2.1 KiB
54 lines
2.1 KiB
4 years ago
|
using System;
|
||
|
using System.Threading;
|
||
|
|
||
|
namespace AX.Network.Common
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// 该类可以生成 64 位全局唯一 ID,适合在分布式服务器集群中产生唯一 ID。
|
||
|
/// </summary>
|
||
|
/// <remarks>
|
||
|
/// 该类生成的 ID 比 System.Guid 节省一倍空间。支持每秒生成 1048576 个不重复的 ID。
|
||
|
/// 它由 时间戳 + 大区号 + 小区号 + 本地递增序号 组成。
|
||
|
/// 时间戳: 32bit
|
||
|
/// 大区号: 4bit
|
||
|
/// 小区号: 8bit
|
||
|
/// 递增序号: 20bit
|
||
|
/// 即支持大区 16 个,每个大区下支持 256 个小区,每个小区里支持每秒生成 1048576 个唯一 ID。
|
||
|
/// </remarks>
|
||
|
public static class GUID
|
||
|
{
|
||
|
private static ulong TimestampMask = 0xffffffff00000000; //时间戳掩码
|
||
|
private static ulong BigMask = 0x00000000f0000000; //大区号掩码
|
||
|
private static ulong SmallMask = 0x000000000ff00000; //小区号掩码
|
||
|
private static ulong BaseMask = 0x00000000000fffff; //本地 ID 编号掩码
|
||
|
private static int BaseId = 0; //本地 ID
|
||
|
|
||
|
private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||
|
private static readonly DateTime BaseTime = DateTime.Now;
|
||
|
|
||
|
/// <summary>
|
||
|
/// 根据大区号和小区号生成 ID。
|
||
|
/// </summary>
|
||
|
public static ulong NewGuid(uint big, uint small)
|
||
|
{
|
||
|
ulong timeStamp = (ulong)(DateTime.UtcNow - Jan1st1970).TotalSeconds;
|
||
|
|
||
|
ulong newId = ((timeStamp << 32) & TimestampMask) |
|
||
|
((big << 28) & BigMask) |
|
||
|
((small << 20) & SmallMask) |
|
||
|
((uint)BaseId & BaseMask);
|
||
|
|
||
|
Interlocked.Increment(ref BaseId);
|
||
|
|
||
|
return newId;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 获得 Id。
|
||
|
/// </summary>
|
||
|
public static long NewGuid()
|
||
|
{
|
||
|
return (long)(NewGuid(15, 255)) + (DateTime.Now - BaseTime).Ticks;
|
||
|
}
|
||
|
}
|
||
|
}
|