github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/uuid/32byte/uuid.go (about)

     1  /* For license and copyright information please see LEGAL file in repository */
     2  
     3  package uuid
     4  
     5  import (
     6  	"crypto/rand"
     7  	"encoding/base64"
     8  	"io"
     9  
    10  	"golang.org/x/crypto/sha3"
    11  
    12  	"github.com/GeniusesGroup/libgo/binary"
    13  	"github.com/GeniusesGroup/libgo/protocol"
    14  	"github.com/GeniusesGroup/libgo/time/unix"
    15  )
    16  
    17  type UUID [32]byte
    18  
    19  func (id UUID) UUID() [32]byte     { return id }
    20  func (id UUID) ID() protocol.ID    { return id.id() }
    21  func (id UUID) IDasString() string { return base64.RawURLEncoding.EncodeToString(id[:8]) }
    22  func (id UUID) ToString() string   { return "TODO:::" }
    23  func (id UUID) ExistenceTime() protocol.Time {
    24  	var time unix.Time
    25  	time.ChangeTo(unix.SecElapsed(id.secondElapsed()), id.nanoSecondElapsed())
    26  	return &time
    27  }
    28  
    29  // New will generate 32 byte time based UUID.
    30  // **CAUTION**: Use for ObjectID in a clustered software without any hash cause all writes always go to one node.
    31  // 99.999999% collision free on distribution generation!
    32  func (id *UUID) New() {
    33  	var err error
    34  	_, err = io.ReadFull(rand.Reader, id[12:])
    35  	if err != nil {
    36  		// TODO::: make random by other ways
    37  	}
    38  
    39  	// Set time to UUID
    40  	var now = unix.Now()
    41  	id.setSecondElapsed(now.SecondElapsed())
    42  	id.setNanoSecondElapsed(now.NanoSecondElapsed())
    43  }
    44  
    45  // NewHash generate 32 byte incremental by time + hash of data UUID
    46  // CAUTION::: Use for ObjectID in a clustered software cause all writes always go to one node!
    47  // 99.999% collision free on distribution generation.
    48  func (id *UUID) NewHash(data []byte) {
    49  	*id = sha3.Sum256(data)
    50  }
    51  
    52  // NewRandom generate 32 byte random UUID.
    53  // CAUTION::: Not use in distribution platforms!
    54  func (id *UUID) NewRandom() {
    55  	var err error
    56  	_, err = io.ReadFull(rand.Reader, id[:])
    57  	if err != nil {
    58  		// TODO::: make random by other ways
    59  	}
    60  }
    61  
    62  func (id UUID) id() protocol.ID             { return protocol.ID(binary.LittleEndian.Uint64(id[0:])) }
    63  func (id UUID) secondElapsed() int64        { return int64(binary.LittleEndian.Uint64(id[0:])) }
    64  func (id UUID) nanoSecondElapsed() int32    { return int32(binary.LittleEndian.Uint32(id[8:])) }
    65  func (id *UUID) setSecondElapsed(sec int64) { binary.LittleEndian.PutUint64(id[0:], uint64(sec)) }
    66  func (id *UUID) setNanoSecondElapsed(nsec int32) {
    67  	binary.LittleEndian.PutUint32(id[8:], uint32(nsec))
    68  }