mirror of
https://github.com/google/uuid.git
synced 2024-11-28 08:49:08 +02:00
655bf50db9
* Add randomness pool mode for V4 UUID Adds an optional randomness pool mode for Random (Version 4) UUID generation. The pool contains random bytes read from the random number generator on demand in batches. Enabling the pool may improve the UUID generation throughput significantly. Since the pool is stored on the Go heap, this feature may be a bad fit for security sensitive applications. That's why it's implemented as an opt-in feature. * fixup! document thread-safety aspects
77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
// Copyright 2016 Google Inc. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package uuid
|
|
|
|
import "io"
|
|
|
|
// New creates a new random UUID or panics. New is equivalent to
|
|
// the expression
|
|
//
|
|
// uuid.Must(uuid.NewRandom())
|
|
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()
|
|
func NewString() string {
|
|
return Must(NewRandom()).String()
|
|
}
|
|
|
|
// NewRandom returns a Random (Version 4) UUID.
|
|
//
|
|
// The strength of the UUIDs is based on the strength of the crypto/rand
|
|
// package.
|
|
//
|
|
// Uses the randomness pool if it was enabled with EnableRandPool.
|
|
//
|
|
// 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.
|
|
func NewRandom() (UUID, error) {
|
|
if !poolEnabled {
|
|
return NewRandomFromReader(rander)
|
|
}
|
|
return newRandomFromPool()
|
|
}
|
|
|
|
// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader.
|
|
func NewRandomFromReader(r io.Reader) (UUID, error) {
|
|
var uuid UUID
|
|
_, err := io.ReadFull(r, uuid[:])
|
|
if err != nil {
|
|
return Nil, err
|
|
}
|
|
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
|
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
|
return uuid, nil
|
|
}
|
|
|
|
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
|
|
}
|
|
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
|
|
return uuid, nil
|
|
}
|