| // 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 | |
| } |