uuid简介
uuid是通用识别码(Universally Unique Identifier)的缩写,它的作用是让分布式系统中的所有元素都具有唯一标识,也可以用来生成数据库中的主键。其要求是所有机器同一时间或不同时间生成的uuid都不一致,这里提供了golang关于30位uuid的实现,参考自MongoDb的ObjectId。

时间戳,8位
获取生成时刻的时间戳,16进制,能用到2106/2/7 14:28:15
计算机名Hash值,6位
读取计算机名字,并调用adler32来生成hash值,再转为16进制
进程Id,8位
调用os.Getpid()来获取进程编号,并转化为16进制
uint32自增值,8位
声明静态自增值count,每次访问count时对count采用原子自增操作,降低碰撞率
实现
import (
"bytes"
"crypto/rand"
"encoding/binary"
"encoding/hex"
"fmt"
"hash/adler32"
"io"
"os"
"sync/atomic"
"time"
)
var machineId = getMachineId()
var processId = getPid()
func getMachineId() []byte {
id := make([]byte, 3)
hostName, err1 := os.Hostname()
fmt.Println(hostName)
if err1 != nil {
_, err2 := io.ReadFull(rand.Reader, id)
if err2 != nil {
panic("无法读取计算机名")
}
return id
}
hash := adler32.New()
hash.Write([]byte(hostName))
copy(id, hash.Sum(nil))
return id
}
func getPid() []byte {
pid := make([]byte, 4)
pidNo := os.Getpid()
pid[0] = byte(pidNo >> 24)
pid[1] = byte(pidNo >> 16)
pid[2] = byte(pidNo >> 8)
pid[3] = byte(pidNo)
return pid
}
type IdGenerator struct {
counter uint32
}
func (generator *IdGenerator) Generate() string {
buffer := bytes.Buffer{}
buffer.Write(generator.getUnix())
buffer.Write(machineId)
buffer.Write(processId)
buffer.Write(generator.getCount())
return hex.EncodeToString(buffer.Bytes())
}
func (generator *IdGenerator) getUnix() []byte {
bytes := make([]byte, 8)
binary.BigEndian.PutUint64(bytes, uint64(time.Now().Unix()))
return bytes[4:]
}
func (generator *IdGenerator) getCount() []byte {
count := atomic.AddUint32(&generator.counter, 1)
countRes := make([]byte, 4)
countRes[0] = byte(count >> 24)
countRes[1] = byte(count >> 16)
countRes[2] = byte(count >> 8)
countRes[3] = byte(count)
return countRes
}