This is a creation in Article, where the information may have evolved or changed.
Package Mainimport ("Errors" "FMT" "Sync" "Time") const (Twepoch = Int64 (1417937700000)//timestamp of default start 1449 473700000. When calculating, subtract this value districtidbits = UINT (5)//area occupied nodeidbits = UINT (9)//node occupies position SEQUENCEB its = UINT (10)//The position occupied by the self-increment ID/* 1 sign bit | 39 Time Stamp | 5 Area | 9 Nodes | 10 (in milliseconds) self-increment ID * 0 | 0000000 00000000 00000000 00000000 00000000 | 00000 | 000000 000 | 000000 0000 * */Maxnodeid =-1 ^ ( -1 << nodeidbits)//node ID maximum range Maxdistrictid =-1 ^ ( -1 << ; districtidbits)//MAX Zone Range Nodeidshift = sequencebits//left shift Districtidshift = Sequencebits + nodeidbits Tim Estampleftshift = sequencebits + nodeidbits + districtidbits sequencemask =-1 ^ ( -1 << sequencebits) MaxN Extidsnum = 100//maximum number of single acquisition IDs) type Idworker struct {sequence int64//ordinal lasttimestamp Int64//Last timestamp Nodei d Int64//Node IDTwepoch Int64 districtid Int64 mutex sync. mutex}//Newidworker new a snowflake ID generator object.func newidworker (NodeId Int64) (*idworker, error) {var distric tId Int64 Districtid = 1//temporarily defaults to 1, convenient for later extension idworker: = &idworker{} if NodeId > Maxnodeid | | NodeId < 0 {fmt. Sprintf ("NodeId Id can ' t is greater than%d or less than 0", Maxnodeid) return nil, errors. New (FMT. Sprintf ("NodeId Id:%d error", NodeId)} if Districtid > Maxdistrictid | | Districtid < 0 {fmt. Sprintf ("District Id can ' t is greater than%d or less than 0", Maxdistrictid) return nil, errors. New (FMT. Sprintf ("District Id:%d error", Districtid)} Idworker.nodeid = NodeId Idworker.districtid = Districtid Idworker . Lasttimestamp =-1 idworker.sequence = 0 Idworker.twepoch = Twepoch Idworker.mutex = sync. mutex{} fmt. Sprintf ("Worker starting. Timestamp left shift%d, District ID bits%d, worker ID bits%d, sequence bits%d, Workerid%d ", TimesTampleftshift, Districtidbits, Nodeidbits, Sequencebits, NodeId) return idworker, nil}//Timegen generate a Unix millise Cond.func Timegen () Int64 {return time. Now (). Unixnano ()/Int64 (time. Millisecond)}//tilnextmillis spin wait till next Millisecond.func tilnextmillis (Lasttimestamp Int64) Int64 {timestamp : = Timegen () for timestamp <= lasttimestamp {timestamp = Timegen ()} return timestamp}//NextID get a SNOWF Lake Id.func (ID *idworker) NextID () (Int64, error) {Id.mutex.Lock () defer id.mutex.Unlock () return Id.nextid ()}// Nextids get snowflake Ids.func (ID *idworker) nextids (num int) ([]int64, error) {if num > maxnextidsnum | | num < 0 {fmt. Sprintf ("Nextids num can ' t is greater than%d or less than 0", Maxnextidsnum) return nil, errors. New (FMT. Sprintf ("Nextids num:%d error", num)} ids: = Make ([]int64, num) id.mutex.Lock () defer id.mutex.Unlock () for I : = 0; i < num; i++ {Ids[i], _ = Id.nextid ()} return IDs, nIl}func (ID *idworker) NextID () (Int64, error) {timestamp: = Timegen () if timestamp < Id.lasttimestamp {// Fmt. Sprintf ("clock is moving backwards. Rejecting requests until%d. ", Id.lasttimestamp) return 0, errors. New (FMT. Sprintf ("Clock moved backwards. Refusing to generate ID for%d milliseconds ", id.lasttimestamp-timestamp)} if Id.lasttimestamp = = Timestamp {i D.sequence = (id.sequence + 1) & Sequencemask if id.sequence = = 0 {timestamp = Tilnextmillis (id.lasttime Stamp)}}} else {id.sequence = 0} Id.lasttimestamp = timestamp return ((Timestamp-id.twepoch) <&L T Timestampleftshift) | (Id.districtid << Districtidshift) | (Id.nodeid << Nodeidshift) | Id.sequence, nil}