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