C#生成唯一ID的几种方式
|
admin
2024年11月15日 20:57
本文热度 100
|
唯一ID是我们在编码的时候经常需要解决的需求。以下是几种常见的 ID 生成方式的实现示例:1. 基于 Snowflake 算法的 ID 生成器Snowflake 是 Twitter 开源的分布式 ID 生成算法,生成的是一个 64 位的整数 ID。using System;
using System.Threading;
public class SnowflakeIdGenerator
{
private const int TimestampBits = 41;
private const int MachineIdBits = 10;
private const int SequenceBits = 12;
private const long MaxMachineId = (1L << MachineIdBits) - 1;
private const long MaxSequence = (1L << SequenceBits) - 1;
private static readonly DateTime Epoch = new DateTime(2023, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private readonly long _machineId;
private long _sequence = 0L;
private long _lastTimestamp = -1L;
private readonly object _lock = new object();
public SnowflakeIdGenerator(long machineId)
{
if (machineId < 0 || machineId > MaxMachineId)
throw new ArgumentException($"Machine ID must be between 0 and {MaxMachineId}.");
_machineId = machineId;
}
public long GenerateId()
{
lock (_lock)
{
long timestamp = GetCurrentTimestamp();
if (timestamp < _lastTimestamp)
throw new InvalidOperationException("Clock moved backwards.");
if (timestamp == _lastTimestamp)
{
_sequence = (_sequence + 1) & MaxSequence;
if (_sequence == 0)
timestamp = WaitNextMillis(_lastTimestamp);
}
else
{
_sequence = 0L;
}
_lastTimestamp = timestamp;
return (timestamp << (MachineIdBits + SequenceBits))
| (_machineId << SequenceBits)
| _sequence;
}
}
private long GetCurrentTimestamp()
{
return (long)(DateTime.UtcNow - Epoch).TotalMilliseconds;
}
private long WaitNextMillis(long lastTimestamp)
{
long timestamp = GetCurrentTimestamp();
while (timestamp <= lastTimestamp)
{
timestamp = GetCurrentTimestamp();
}
return timestamp;
}
}
var generator = new SnowflakeIdGenerator(1); // 传入机器 ID
long id = generator.GenerateId();
Console.WriteLine(id); // 输出一个 64 位整数
using System;
public class TimestampIdGenerator
{
private static readonly Random Random = new Random();
public string GenerateId(string prefix = "")
{
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
int random = Random.Next(1000, 9999);
return $"{prefix}{timestamp}{random}";
}
}
var generator = new TimestampIdGenerator();
string id = generator.GenerateId("ORDER-");
Console.WriteLine(id); // 输出类似:ORDER-16970496000001234
using System;
public class GuidIdGenerator
{
public string GenerateId()
{
return Guid.NewGuid().ToString();
}
}
var generator = new GuidIdGenerator();
string id = generator.GenerateId();
Console.WriteLine(id); // 输出类似:550e8400-e29b-41d4-a716-446655440000
使用 Redis 的 INCR 命令生成全局唯一的自增 ID。using StackExchange.Redis;
public class RedisIdGenerator
{
private readonly IDatabase _redisDb;
public RedisIdGenerator(string connectionString)
{
var redis = ConnectionMultiplexer.Connect(connectionString);
_redisDb = redis.GetDatabase();
}
public long GenerateId(string key = "global:id")
{
return _redisDb.StringIncrement(key);
}
}
var generator = new RedisIdGenerator("localhost");
long id = generator.GenerateId();
Console.WriteLine(id); // 输出自增的 ID
using System;
public class CustomIdGenerator
{
private static readonly Random Random = new Random();
public string GenerateId(string prefix)
{
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
int random = Random.Next(1000, 9999);
return $"{prefix}-{timestamp}-{random}";
}
}
var generator = new CustomIdGenerator();
string id = generator.GenerateId("USER");
Console.WriteLine(id); // 输出类似:USER-1697049600000-1234
MongoDB 使用 ObjectId 作为默认的唯一标识符,它是一个 12 字节的十六进制字符串。using MongoDB.Bson;
ObjectId id = ObjectId.GenerateNewId();
Console.WriteLine(id); // 输出类似:507f1f77bcf86cd799439011
该文章在 2025/2/12 10:48:23 编辑过