~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/rogpeppe/fastuuid/uuid.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Package fastuuid provides fast UUID generation of 192 bit
 
2
// universally unique identifiers. It does not provide
 
3
// formatting or parsing of the identifiers (it is assumed
 
4
// that a simple hexadecimal or base64 representation
 
5
// is sufficient, for which adequate functionality exists elsewhere).
 
6
//
 
7
// Note that the generated UUIDs are not unguessable - each
 
8
// UUID generated from a Generator is adjacent to the
 
9
// previously generated UUID.
 
10
//
 
11
// It ignores RFC 4122.
 
12
package fastuuid
 
13
 
 
14
import (
 
15
        "crypto/rand"
 
16
        "encoding/binary"
 
17
        "errors"
 
18
        "sync/atomic"
 
19
)
 
20
 
 
21
// Generator represents a UUID generator that
 
22
// generates UUIDs in sequence from a random starting
 
23
// point.
 
24
type Generator struct {
 
25
        seed    [24]byte
 
26
        counter uint64
 
27
}
 
28
 
 
29
// NewGenerator returns a new Generator.
 
30
// It can fail if the crypto/rand read fails.
 
31
func NewGenerator() (*Generator, error) {
 
32
        var g Generator
 
33
        _, err := rand.Read(g.seed[:])
 
34
        if err != nil {
 
35
                return nil, errors.New("cannot generate random seed: " + err.Error())
 
36
        }
 
37
        return &g, nil
 
38
}
 
39
 
 
40
// MustNewGenerator is like NewGenerator
 
41
// but panics on failure.
 
42
func MustNewGenerator() *Generator {
 
43
        g, err := NewGenerator()
 
44
        if err != nil {
 
45
                panic(err)
 
46
        }
 
47
        return g
 
48
}
 
49
 
 
50
// Next returns the next UUID from the generator.
 
51
// Only the first 8 bytes can differ from the previous
 
52
// UUID, so taking a slice of the first 16 bytes
 
53
// is sufficient to provide a somewhat less secure 128 bit UUID.
 
54
//
 
55
// It is OK to call this method concurrently.
 
56
func (g *Generator) Next() [24]byte {
 
57
        x := atomic.AddUint64(&g.counter, 1)
 
58
        var counterBytes [8]byte
 
59
        binary.LittleEndian.PutUint64(counterBytes[:], x)
 
60
 
 
61
        uuid := g.seed
 
62
        for i, b := range counterBytes {
 
63
                uuid[i] ^= b
 
64
        }
 
65
        return uuid
 
66
}