Golang时序ID生成器

C 2023-11-8 3661

设计思路:时序型索引

使用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()))
}
最新回复 (0)
    • 屌丝论坛
      2