Jquery中文网 www.jquerycn.cn
Jquery中文网 >  后端编程  >  Go语言  >  正文 GoLang雪花算法和反推

GoLang雪花算法和反推

发布时间:2021-04-12   编辑:www.jquerycn.cn
jquery中文网为您提供GoLang雪花算法和反推等资源,欢迎您收藏本站,我们将为您提供最新的GoLang雪花算法和反推资源

工具代码

package log

import (
	"crypto/md5"
	"crypto/rand"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"io"
	"os"
	"sync/atomic"
	"time"
)

// LogId is a unique ID identifying a log record. It must be exactly 12 bytes
// long.
//
// Reference:http://www.mongodb.org/display/DOCS/Object IDs
type ObjectId [12]byte

var (
	// objectIdCounter is atomically incremented when generating a new ObjectId
	// using NewObjectId() function. It's used as a counter part of an id.
	objectIdCounter uint64 = 0

	// machineId stores machine id generated once and used in subsequent calls
	// to NewObjectId function.
	machineId = initMachineId()
)

// readMachineId generates machine id and puts it into the machineId global
// variable. If this function fails to get the hostname, it will cause
// a runtime error.
func initMachineId() []byte {
	var sum [3]byte
	id := sum[:]
	hostname, err1 := os.Hostname()
	if err1 != nil {
		_, err2 := io.ReadFull(rand.Reader, id)
		if err2 != nil {
			panic(fmt.Errorf("cannot get hostname: %v; %v", err1, err2))
		}
		return id
	}
	hw := md5.New()
	hw.Write([]byte(hostname))
	copy(id, hw.Sum(nil))
	return id
}

func StrToObjectId(str string) ObjectId {
	byteArr,err := hex.DecodeString(str)
	if err != nil {
		panic(err.Error())
	}

	var b[12]byte
	i := 0
	for {
		if i == 12{
			break
		}
		b[i] = byteArr[i]
		i  
	}

	return b
}

// NewObjectId returns a new unique ObjectId.
func NewObjectId() ObjectId {
	var b [12]byte
	// Timestamp, 4 bytes, big endian
	binary.BigEndian.PutUint32(b[:], uint32(time.Now().Unix()))
	// Machine, first 3 bytes of md5(hostname)
	b[4] = machineId[0]
	b[5] = machineId[1]
	b[6] = machineId[2]
	// Pid, 2 bytes, specs don't specify endianness, but we use big endian.
	pid := os.Getpid()
	b[7] = byte(pid >> 8)
	b[8] = byte(pid)
	// Increment, 3 bytes, big endian
	i := atomic.AddUint64(&objectIdCounter, 1)
	b[9] = byte(i >> 16)
	b[10] = byte(i >> 8)
	b[11] = byte(i)
	return b
}

// NewObjectIdWithTime returns a dummy ObjectId with the timestamp part filled
// with the provided number of seconds from epoch UTC, and all other parts
// filled with zeroes. It's not safe to insert a document with an id generated
// by this method, it is useful only for queries to find documents with ids
// generated before or after the specified timestamp.
func NewObjectIdWithTime(t time.Time) ObjectId {
	var b [12]byte
	binary.BigEndian.PutUint32(b[:4], uint32(t.Unix()))
	return b
}

func NewObjectIdWithHexString(s string) (o ObjectId) {
	d, err := hex.DecodeString(s)
	if err != nil || len(d) != 12 {
		panic(fmt.Sprintf("invalid input to ObjectIdHex: %q", s))
	}
	copy(o[:], d[:12])
	return
}

// Hex returns a hex representation of the ObjectId.
func (id ObjectId) Hex() string {
	return hex.EncodeToString(id[:])
}

// Time returns the timestamp part of the id.
// It's a runtime error to call this method with an invalid id.
func (id ObjectId) Time() time.Time {
	// First 4 bytes of ObjectId is 32-bit big-endian seconds from epoch.
	secs := int64(binary.BigEndian.Uint32(id[:4]))
	return time.Unix(secs, 0)
}

// Machine returns the 3-byte machine id part of the id.
// It's a runtime error to call this method with an invalid id.
func (id ObjectId) Machine() []byte {
	return id[4:7]
}

// Pid returns the process id part of the id.
// It's a runtime error to call this method with an invalid id.
func (id ObjectId) Pid() uint16 {
	return binary.BigEndian.Uint16(id[7:9])
}

// Counter returns the incrementing value part of the id.
// It's a runtime error to call this method with an invalid id.
func (id ObjectId) Counter() int32 {
	b := id[9:12]
	// Counter is stored as big-endian 3-byte value
	return int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2]))
}

测试:

func main() {
	id := log.NewObjectId().Hex()
	fmt.Println(id)
	logId := log.StrToObjectId(id)
	fmt.Println(logId.Hex())
	fmt.Println(logId.Time())
	fmt.Println(logId.Machine())
	fmt.Println(logId.Pid())
	fmt.Println(logId.Counter())
}

结果:
whydeMacBook-Pro:go why$ go run test.go
5e394e99a7f8a34d810303d4
5e394e99a7f8a34d810303d4
2020-02-04 18:59:37  0800 CST
[167 248 163]
19841
1

 

 

到此这篇关于“GoLang雪花算法和反推”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
想系统学习GO语言(Golang
如何使用HTML5 canvas实现雪花飘落
GoLang雪花算法和反推
Illustrator绘制有型有色的抽象派玫瑰花教程分享
用canvas实现简单的下雪效果(附代码)
Golang 中 RSA 算法的使用
golang基础教程
拓展学习-golang的基础语法和常用开发工具
利用SurfaceView实现下雨与下雪动画的效果
用Golang写一个搜索引擎(0x0B)--- 第一部分结束

[关闭]