经测试,最快的一种

public class Generator
{
// should be between 40 (34 years) and 42 (139 years)
internal const int NumberOfTimeBits = ; // should be between 0 (single generator) and 10 (1024 generators)
internal const int NumberOfGeneratorIdBits = ; // should be 10 at least (4096 unique ids per millisecond per generator)
internal const int NumberOfSequenceBits = - NumberOfTimeBits - NumberOfGeneratorIdBits; private readonly byte[] _buffer = new byte[];
private readonly byte[] _timeBytes = new byte[];
private readonly byte[] _idBytes = new byte[];
private readonly byte[] _sequenceBytes = new byte[];
private readonly int _maxSequence = (int)Math.Pow(, NumberOfSequenceBits) - ;
private readonly DateTime _start; private short _sequence;
private long _previousTime; /// <summary>
/// Instantiate the generator. Each Generator should have its own ID, so you can
/// use multiple Generator instances in a cluster. All generated IDs are unique
/// provided the start date newer changes. I recommend to choose January 1, 2013.
/// </summary>
public Generator(short generatorId, DateTime start)
{
if (generatorId < || generatorId >= Math.Pow(, NumberOfGeneratorIdBits))
{
var msg = string.Format(
CultureInfo.InvariantCulture,
"generator id must be between 0 (inclusive) and {0} (exclusive).",
Math.Pow(, NumberOfGeneratorIdBits));
throw new ArgumentException(msg, "generatorId");
}
if (start > DateTime.Today)
{
throw new ArgumentException("start date must not be in the future.", "start");
} CalculateIdBytes(generatorId);
_start = start;
} /// <summary>
/// Can generate up to 4096 different IDs per millisecond.
/// </summary>
public string Next()
{
SpinToNextSequence();
WriteValuesToByteArray(_buffer, _previousTime, _sequence); //return DateTime.Now.ToString("yyyyMMddHH")+Convert.ToBase64String(_buffer); 这样有更好的排序
return Convert.ToBase64String(_buffer);
} public ulong NextLong()
{
SpinToNextSequence();
WriteValuesToByteArray(_buffer, _previousTime, _sequence); Array.Reverse(_buffer);
return BitConverter.ToUInt64(_buffer, );
} internal unsafe void WriteValuesToByteArray(byte[] target, long time, short sequence)
{
fixed (byte* arrayPointer = target)
{
*(long*)arrayPointer = ;
} fixed (byte* arrayPointer = _timeBytes)
{
*(long*)arrayPointer = time << ( - NumberOfTimeBits);
} fixed (byte* arrayPointer = _sequenceBytes)
{
*(short*)arrayPointer = sequence;
} WriteValuesToByteArray(target, _timeBytes, _idBytes, _sequenceBytes);
} private unsafe void CalculateIdBytes(short id)
{
fixed (byte* arrayPointer = _idBytes)
{
*(short*)arrayPointer = (short)(id << ( - (( - NumberOfSequenceBits) % )));
}
} [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void WriteValuesToByteArray(byte[] target, byte[] time, byte[] id, byte[] sequence)
{
//// 1234567890123456789012
//// time: 1111111111111111111111111111111111111111110000
//// id: 0011111111110000
//// seq: 0000111111111111
////
//// 000000000000000100010111101010100001000010 0000001011 000000000000
//// pos: 0 1 2 3 4 5 6
//// byte: 0 1 2 3 4 5 6 7 target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]);
target[] = (byte)(target[] | time[]); target[] = (byte)(target[] | id[]);
target[] = (byte)(target[] | id[]); target[] = (byte)(target[] | sequence[]);
target[] = (byte)(target[] | sequence[]);
} private void SpinToNextSequence()
{
var time = GetTime(); while (time == _previousTime && _sequence >= _maxSequence)
{
time = GetTime();
} _sequence = time == _previousTime ? (short)(_sequence + ) : (short);
_previousTime = time;
} [MethodImpl(MethodImplOptions.AggressiveInlining)]
private long GetTime()
{
return (long)(DateTime.UtcNow - _start).TotalMilliseconds;
}
}

gihub地址:https://github.com/mschuler/UniqueIdGenerator

生成分布式随机ID的更多相关文章

  1. 雪花算法,生成分布式唯一ID

    2.3 基于算法实现 [转载] 这里介绍下Twitter的Snowflake算法——snowflake,它把时间戳,工作机器id,序列号组合在一起,以保证在分布式系统中唯一性和自增性. snowfla ...

  2. 高并发情况下,如何生成分布式全局id

    1.使用UUID生成全局id,不占用宽带 2.基于数据库自增或者序列生成全局id,占用宽带,设置自增步长实现集群,但可扩展性差 3.基于redis生成全局id,占用宽度,设置自增步长实现集群,性能比数 ...

  3. Zookeeper命名服务——生成分布式有序且唯一id

    生成分布式有序且唯一id的方法有很多种,使用zookeeper是比较简单的一种方法,只是生成的速度不高,这里只是一个借助zk的版本号生成分布式唯一且有序id的例子. ZkIdGenerator.jav ...

  4. 高并发情况下分布式全局ID

    1.高并发情况下,生成分布式全局id策略2.利用全球唯一UUID生成订单号优缺点3.基于数据库自增或者序列生成订单号4.数据库集群如何考虑数据库自增唯一性5.基于Redis生成生成全局id策略6.Tw ...

  5. 分布式唯一id:snowflake算法思考

    匠心零度 转载请注明原创出处,谢谢! 缘起 为什么会突然谈到分布式唯一id呢?原因是最近在准备使用RocketMQ,看看官网介绍: 一句话,消息可能会重复,所以消费端需要做幂等.为什么消息会重复后续R ...

  6. 分布式Unique ID的生成方法

    分布式Unique ID的生成方法 分布式的Unique ID的用途如此广泛,从业务对象Id到日志的TraceId,本文总结了林林总总的各种生成算法. 1. 发号器 我接触的最早的Unique ID, ...

  7. [转帖]分布式Unique ID的生成方法一览

    分布式Unique ID的生成方法一览 http://www.importnew.com/22211.html 分布式的Unique ID的用途如此广泛,从业务对象Id到日志的TraceId,本文总结 ...

  8. 分布式全局ID生成方案

    传统的单体架构的时候,我们基本是单库然后业务单表的结构.每个业务表的ID一般我们都是从1增,通过AUTO_INCREMENT=1设置自增起始值,但是在分布式服务架构模式下分库分表的设计,使得多个库或多 ...

  9. 分布式全局ID的几种生成方案

    前言 在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等. 那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是 ...

随机推荐

  1. os如何处理键盘的所有按键,显示or不显示,显示是如何显示

    [0]README 0.1) source code and text decription are from orange's implemention of a os , and for comp ...

  2. ES6之路

    从工作到现在,虽然是PHP出身,一直都和JS形影不离,从JQ和原生处理页面,到后来被angular1的MVVM模式惊艳到,再到弃angular转战vue,到现在使用react,一路走来,跳坑无数,现在 ...

  3. 设置Eclipse中properties文件打开方式myeclipse一样有source和properties两个视图方法

    东北大亨: 说明:如果想在eclipse的properties文件打开的方式出现source和properties视图就需要添加JBossTools插件 下面介绍如果添加插件: 1.打开官网 http ...

  4. WebStorm 调试JavaScript

    WebStorm强大的调试JavaScript功能 Vue项目调试总结-WebStorm+Chrome调试 WebStorm+Chrome插件JetBrains IDE Support进行实时调试 W ...

  5. SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组

    SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...

  6. 单例模式(Mongo对象的创建)

    单例模式: 饿汉式单例 //饿汉式单例类.在类初始化时,已经自行实例化 public class Singleton1 { //私有的默认构造子 private Singleton1() {} //已 ...

  7. 九度OJ 1175:打牌 (模式匹配)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:8156 解决:1560 题目描述: 牌只有1到9,手里拿着已经排好序的牌a,对方出牌b,用程序判断手中牌是否能够压过对方出牌.  规则:出牌 ...

  8. IIS的ARR实现站点的负载均衡 nginx 对比

    windows下使用IIS的ARR实现站点的负载均衡 - CSDN博客 https://blog.csdn.net/zzy7075/article/details/73294713 IIS的ARR实现 ...

  9. UVA11330 Andy's Shoes —— 置换分解

    题目链接:https://vjudge.net/problem/UVA-11330 题意: 给出n双鞋子,鞋子按左右左右地摆放,但“左右”是否为一对鞋子是不确定的.问:至少交换多少次鞋子,才能把每双鞋 ...

  10. ZOJ - 3430 Detect the Virus —— AC自动机、解码

    题目链接:https://vjudge.net/problem/ZOJ-3430 Detect the Virus Time Limit: 2 Seconds      Memory Limit: 6 ...