-
Notifications
You must be signed in to change notification settings - Fork 378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add uuid v6, v7 #138
add uuid v6, v7 #138
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,15 +9,15 @@ import "io" | |
// New creates a new random UUID or panics. New is equivalent to | ||
// the expression | ||
// | ||
// uuid.Must(uuid.NewRandom()) | ||
// uuid.Must(uuid.NewRandom()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change impacts godoc, please do not change the formatting. |
||
func New() UUID { | ||
return Must(NewRandom()) | ||
} | ||
|
||
// NewString creates a new random UUID and returns it as a string or panics. | ||
// NewString is equivalent to the expression | ||
// | ||
// uuid.New().String() | ||
// uuid.New().String() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change impacts godoc, please do not change the formatting. |
||
func NewString() string { | ||
return Must(NewRandom()).String() | ||
} | ||
|
@@ -31,11 +31,11 @@ func NewString() string { | |
// | ||
// A note about uniqueness derived from the UUID Wikipedia entry: | ||
// | ||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being | ||
// hit by a meteorite is estimated to be one chance in 17 billion, that | ||
// means the probability is about 0.00000000006 (6 × 10−11), | ||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a | ||
// year and having one duplicate. | ||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being | ||
// hit by a meteorite is estimated to be one chance in 17 billion, that | ||
// means the probability is about 0.00000000006 (6 × 10−11), | ||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a | ||
// year and having one duplicate. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change impacts godoc, please do not change the formatting. |
||
func NewRandom() (UUID, error) { | ||
if !poolEnabled { | ||
return NewRandomFromReader(rander) | ||
|
@@ -57,18 +57,9 @@ func NewRandomFromReader(r io.Reader) (UUID, error) { | |
|
||
func newRandomFromPool() (UUID, error) { | ||
var uuid UUID | ||
poolMu.Lock() | ||
if poolPos == randPoolSize { | ||
_, err := io.ReadFull(rander, pool[:]) | ||
if err != nil { | ||
poolMu.Unlock() | ||
return Nil, err | ||
} | ||
poolPos = 0 | ||
if err := fill16BytesFromPool(uuid[:]); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To gain the same effect, you could move lines 64 and 65 up to NewRandom:
But I actually do not see the need for that change (which will also add and extra comparison to the generation of random UUIDs). I don't think any change is needed here as it will not impact the v7 code. See the comment on generating V7 UUIDs (in which case you want not changes to this file). |
||
return Nil, err | ||
} | ||
copy(uuid[:], pool[poolPos:(poolPos+16)]) | ||
poolPos += 16 | ||
poolMu.Unlock() | ||
|
||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 | ||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright 2018 Google Inc. All rights reserved. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/2018/2023 |
||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package uuid | ||
|
||
import "encoding/binary" | ||
|
||
// NewV6 returns a Version 6 UUID based on the current NodeID and clock | ||
// sequence, and the current time. If the NodeID has not been set by SetNodeID | ||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot | ||
// be set NewV6 returns nil. If clock sequence has not been set by | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NewV6 cannot return nil, but can return Nil (16 bytes of zero). The NodeID is always set. Rather than an error it simply returns a random set of bits as the NodeID. |
||
// SetClockSequence then it will be set automatically. If GetTime fails to | ||
// return the current NewV6 returns nil and an error. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a reference to the standard that defines Version 6 UUIDs. |
||
func NewV6() (UUID, error) { | ||
var uuid UUID | ||
now, seq, err := GetTime() | ||
if err != nil { | ||
return uuid, err | ||
} | ||
|
||
binary.BigEndian.PutUint64(uuid[0:], uint64(now)) | ||
binary.BigEndian.PutUint16(uuid[8:], seq) | ||
|
||
uuid[6] = 0x60 | (uuid[6] & 0x0F) | ||
uuid[8] = 0x80 | (uuid[8] & 0x3F) | ||
|
||
nodeMu.Lock() | ||
if nodeID == zeroID { | ||
setNodeInterface("") | ||
} | ||
copy(uuid[10:], nodeID[:]) | ||
nodeMu.Unlock() | ||
|
||
return uuid, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright 2018 Google Inc. All rights reserved. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/2018/2023 |
||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package uuid | ||
|
||
import ( | ||
"encoding/binary" | ||
"io" | ||
) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the following functions can replace these functions:
They need comments, of course. Putting in the bytes directly rather than using Note that uuid[8] already has the right version number in it. |
||
func unixepoch() (uint64, error) { | ||
now, _, err := GetTime() | ||
if err != nil { | ||
return 0, err | ||
} | ||
|
||
sec, nsec := now.UnixTime() | ||
return uint64(sec*1000 + nsec/1000000), nil | ||
} | ||
|
||
func NewV7FromReader(r io.Reader) (UUID, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This must have a godoc comment and also needs to reference the standard that defines version 7 UUIDs. |
||
var uuid UUID | ||
|
||
t, err := unixepoch() | ||
if err != nil { | ||
return uuid, err | ||
} | ||
|
||
binary.BigEndian.PutUint64(uuid[0:], t<<16) | ||
_, err = io.ReadFull(r, uuid[6:]) | ||
if err != nil { | ||
return Nil, err | ||
} | ||
|
||
uuid[6] = 0x70 | (uuid[6] & 0x0F) | ||
uuid[8] = 0x80 | (uuid[8] & 0x3F) | ||
|
||
return uuid, nil | ||
} | ||
|
||
func newV7FromPool() (UUID, error) { | ||
var uuid UUID | ||
|
||
t, err := unixepoch() | ||
if err != nil { | ||
return uuid, err | ||
} | ||
|
||
if err = fill16BytesFromPool(uuid[:]); err != nil { | ||
return Nil, err | ||
} | ||
|
||
binary.BigEndian.PutUint32(uuid[0:], uint32(t>>16)) | ||
binary.BigEndian.PutUint16(uuid[4:], uint16(t)) | ||
|
||
uuid[6] = 0x70 | (uuid[6] & 0x0F) | ||
uuid[8] = 0x80 | (uuid[8] & 0x3F) | ||
|
||
return uuid, nil | ||
} | ||
|
||
// NewV7 returns a Version 7 UUID based on the current time. | ||
// If GetTime fails to return the current NewV7 returns nil and an error. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It returns Nil, not nil, but only when it is unable to generate random data (see above while there will be no error in getting the current time). |
||
func NewV7() (UUID, error) { | ||
if !poolEnabled { | ||
return NewV7FromReader(rander) | ||
} | ||
return newV7FromPool() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments from version4.go