Transferred from: http://blog.csdn.net/kinwyb/article/details/50238505
Use Twitter's snowflake algorithm to generate a unique ID.
In the distributed system, the need to generate global uid or more, Twitter's snowflake to solve this demand, the implementation is still very simple, remove the configuration information, the core code is the millisecond time 41 bits + Machine ID 10 bit + milliseconds sequence 12 bits.
/// <summary> ///generate a unique ID based on Twitter's snowflake algorithm///Snowflake algorithm 64-bit///0---0000000000 0000000000 0000000000 0000000000 0---00000---00000---000000000000///The first bit is unused (it can actually also be used as a long sign bit), the next 41 bits are millisecond time, then the 5 bit datacenter identifies the bit, the 5-bit machine ID (not the identifier, is actually the thread identity), and then 12 bits within the millisecond of the current count of milliseconds, Add up to just 64 bits, for a long type. ///where the datacenter identity bit start is the machine bit, the machine ID is actually the thread identity, can be the same as one by one 10-bit to represent different machines/// </summary> Public classIdworker {//Machine ID Private Static LongWorkerid; Private Static LongTwepoch =687888001020L;//The only time, this is a random amount to avoid repetition, self-setting not greater than the current timestamp Private Static Longsequence =0L; Private Static intWorkeridbits =4;//The number of machine code bytes. 4 bytes to save the machine code Public Static LongMaxworkerid =-1L^ -1L<< workeridbits;//Max Machine ID Private Static intSequencebits =Ten;//number of counter bytes, 10 bytes to save the digital count Private Static intWorkeridshift = sequencebits;//the number of left shifts in the machine code data is the number of digits occupied by the rear counter Private Static intTimestampleftshift = sequencebits + workeridbits;//the time stamp left moves the number of bits is the machine code and the counter total byte number Public Static LongSequencemask =-1L^ -1L<< sequencebits;//a count can be generated within a microsecond, and if that value is reached, it waits until the next subtle one is generated. Private LongLasttimestamp =-1L; PublicIdworker (LongWorkerid) { if(Workerid > Maxworkerid | | Workerid <0) Throw NewException (string. Format ("worker Id can ' t be greater than {0} or less than 0", Workerid)); Idworker.workerid=Workerid; } Public LongNextID () {Lock( This) { Longtimestamp =Timegen (); if( This. Lasttimestamp = = timestamp) {//generate ID in the same subtleIdworker.sequence = (idworker.sequence +1) & Idworker.sequencemask;//calculates whether the count generated in this microsecond has reached the upper limit with the & Operation if(Idworker.sequence = =0){ //a subtle inside generated ID count has reached the upper limit, waiting for the next subtletimestamp = Tillnextmillis ( This. Lasttimestamp); } } Else{//generate IDs in different microsecondsIdworker.sequence =0;//Count Clear 0 } if(Timestamp <Lasttimestamp) { //throws an exception if the current timestamp is smaller than the last time the ID was generated, because there is no guarantee that the generated ID was not generated before Throw NewException (string. Format ("Clock moved backwards. Refusing to generate ID for {0} milliseconds", This. Lasttimestamp-timestamp)); } This. Lasttimestamp = timestamp;//saves the current timestamp as the timestamp of the last generated ID LongNextID = (Timestamp-twepoch << timestampleftshift) | Idworker.workerid << Idworker.workeridshift |idworker.sequence; returnNextID; } } /// <summary> ///Get next microsecond timestamp/// </summary> /// <param name= "Lasttimestamp" ></param> /// <returns></returns> Private LongTillnextmillis (LongLasttimestamp) { Longtimestamp =Timegen (); while(Timestamp <=Lasttimestamp) {Timestamp=Timegen (); } returntimestamp; } /// <summary> ///generate the current time stamp/// </summary> /// <returns></returns> Private LongTimegen () {return(Long) (Datetime.utcnow-NewDateTime (1970,1,1,0,0,0, DATETIMEKIND.UTC)). TotalMilliseconds; } }
Twitter's snowflake algorithm (C # version)