github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/identity/randomid.go (about)

     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  }