version6.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // Copyright 2023 Google Inc. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package uuid
  5. import "encoding/binary"
  6. // UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality.
  7. // It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs.
  8. // Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead.
  9. //
  10. // see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6
  11. //
  12. // NewV6 returns a Version 6 UUID based on the current NodeID and clock
  13. // sequence, and the current time. If the NodeID has not been set by SetNodeID
  14. // or SetNodeInterface then it will be set automatically. If the NodeID cannot
  15. // be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by
  16. // SetClockSequence then it will be set automatically. If GetTime fails to
  17. // return the current NewV6 returns Nil and an error.
  18. func NewV6() (UUID, error) {
  19. var uuid UUID
  20. now, seq, err := GetTime()
  21. if err != nil {
  22. return uuid, err
  23. }
  24. /*
  25. 0 1 2 3
  26. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  27. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  28. | time_high |
  29. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  30. | time_mid | time_low_and_version |
  31. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  32. |clk_seq_hi_res | clk_seq_low | node (0-1) |
  33. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  34. | node (2-5) |
  35. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  36. */
  37. binary.BigEndian.PutUint64(uuid[0:], uint64(now))
  38. binary.BigEndian.PutUint16(uuid[8:], seq)
  39. uuid[6] = 0x60 | (uuid[6] & 0x0F)
  40. uuid[8] = 0x80 | (uuid[8] & 0x3F)
  41. nodeMu.Lock()
  42. if nodeID == zeroID {
  43. setNodeInterface("")
  44. }
  45. copy(uuid[10:], nodeID[:])
  46. nodeMu.Unlock()
  47. return uuid, nil
  48. }