zoukankan      html  css  js  c++  java
  • golang产生guid

    labix.org/v2/mgo/bson 包虽然是MongoDB的golang实现,其中产生唯一ID的算法是独立的,不依赖MongoDB, 提炼这部分的代码如下:

     

    package main

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

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

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

    // ObjectId is a unique ID identifying a BSON value. It must be exactly 12 bytes
    // long. MongoDB objects by default have such a property set in their "_id"
    // property.
    //
    // http://www.mongodb.org/display/DOCS/Object+IDs
    type ObjectId string

    func main() {
        objID := NewObjectId()
        fmt.Println(objID)
        fmt.Println(objID.Hex())
    }

    // 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 readMachineId() []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))
        fmt.Println("readMachineId:" + string(id))
        return id
    }

    // NewObjectId returns a new unique ObjectId.
    // 4byte 时间,
    // 3byte 机器ID
    // 2byte pid
    // 3byte 自增ID
    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.AddUint32(&objectIdCounter, 1)
        b[9] = byte(i >> 16)
        b[10] = byte(i >> 8)
        b[11] = byte(i)
        return ObjectId(b[:])
    }

    // Hex returns a hex representation of the ObjectId.
    // 返回16进制对应的字符串
    func (id ObjectId) Hex() string {
        return hex.EncodeToString([]byte(id))
    }

    执行结果截图:

    image

    参考资料:

    mgo说明文档
    http://godoc.org/labix.org/v2/mgo/bson

    Golang binary包——byte数组如何转int?
    http://blog.cyeam.com/hash/2014/07/29/go_bytearraytoint/

  • 相关阅读:
    PAT 顶级 1010 Lehmer Code (35 分)
    PAT 顶级 1010 Lehmer Code (35 分)
    CCF CSP 201909-4 推荐系统
    CCF CSP 201909-4 推荐系统
    Codeforces 1251C Minimize The Integer
    Codeforces 1251C Minimize The Integer
    CCF CSP 201803-4 棋局评估
    CCF CSP 201803-4 棋局评估
    【DP_树形DP专题】题单总结
    【DP_树形DP专题】题单总结
  • 原文地址:https://www.cnblogs.com/ghj1976/p/4259019.html
Copyright © 2011-2022 走看看