Golang时序ID生成器

设计思路:时序型索引

使用Golang实现了一个时序ID生成器,采用8字节[]byte,可容纳公元0年起每秒最多65536个ID。

前5字节是时间戳timer,由于需要容纳较长年份,因此比传统4字节多1字节。

后3字节是计数器counter,记录每秒内的递增数,3字节最长65536。

ID可表示为8字节[]byte,uint64及36进制string。

附一组解码器,返回timer和counter。

package main



import (

	"encoding/binary"

	"fmt"

	"strconv"

	"time"

)



var AidTimer int64

var AidCounter uint16 = 0 // 先限制2位,以后可放宽到3位



func Aid() []byte {

	now := 62135596800 + time.Now().Unix()

	if AidTimer == now {

		AidCounter++

	} else {

		AidTimer = now

		AidCounter = 0

	}

	tB := make([]byte, 8)

	binary.BigEndian.PutUint64(tB, uint64(AidTimer))

	cB := make([]byte, 4)

	binary.BigEndian.PutUint32(cB, uint32(AidCounter))

	return append(tB[3:], cB[1:]...)

}



func Aid10() uint64 {

	return binary.BigEndian.Uint64(Aid())

}



func Aid36() string {

	return strconv.FormatUint(Aid10(), 36)

}



func AidDecoder(aid []byte) (uint64, uint32) {

	timer := binary.BigEndian.Uint64(append(make([]byte, 3), aid[0:5]...))

	counter := binary.BigEndian.Uint32(append(make([]byte, 1), aid[5:]...))

	return timer, counter

}



func Aid10Decoder(aid10 uint64) (uint64, uint32) {

	aid := make([]byte, 8)

	binary.BigEndian.PutUint64(aid, aid10)

	return AidDecoder(aid)

}



func Aid36Decoder(aid36 string) (uint64, uint32) {

	aid10, err := strconv.ParseUint(aid36, 36, 64)

	if err != nil {

		return 0, 0

	}

	return Aid10Decoder(aid10)

}



func main() {

	fmt.Println(AidDecoder(Aid()))

	fmt.Println(Aid10Decoder(Aid10()))

	fmt.Println(Aid36Decoder(Aid36()))

}

C
1