Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / docker / swarmkit / identity / randomid.go
1 package identity
2
3 import (
4         cryptorand "crypto/rand"
5         "fmt"
6         "io"
7         "math/big"
8 )
9
10 var (
11         // idReader is used for random id generation. This declaration allows us to
12         // replace it for testing.
13         idReader = cryptorand.Reader
14 )
15
16 // parameters for random identifier generation. We can tweak this when there is
17 // time for further analysis.
18 const (
19         randomIDEntropyBytes = 17
20         randomIDBase         = 36
21
22         // To ensure that all identifiers are fixed length, we make sure they
23         // get padded out or truncated to 25 characters.
24         //
25         // For academics,  f5lxx1zz5pnorynqglhzmsp33  == 2^128 - 1. This value
26         // was calculated from floor(log(2^128-1, 36)) + 1.
27         //
28         // While 128 bits is the largest whole-byte size that fits into 25
29         // base-36 characters, we generate an extra byte of entropy to fill
30         // in the high bits, which would otherwise be 0. This gives us a more
31         // even distribution of the first character.
32         //
33         // See http://mathworld.wolfram.com/NumberLength.html for more information.
34         maxRandomIDLength = 25
35 )
36
37 // NewID generates a new identifier for use where random identifiers with low
38 // collision probability are required.
39 //
40 // With the parameters in this package, the generated identifier will provide
41 // ~129 bits of entropy encoded with base36. Leading padding is added if the
42 // string is less 25 bytes. We do not intend to maintain this interface, so
43 // identifiers should be treated opaquely.
44 func NewID() string {
45         var p [randomIDEntropyBytes]byte
46
47         if _, err := io.ReadFull(idReader, p[:]); err != nil {
48                 panic(fmt.Errorf("failed to read random bytes: %v", err))
49         }
50
51         p[0] |= 0x80 // set high bit to avoid the need for padding
52         return (&big.Int{}).SetBytes(p[:]).Text(randomIDBase)[1 : maxRandomIDLength+1]
53 }