Skip to content

Commit

Permalink
identity: add pkg for random id generation
Browse files Browse the repository at this point in the history
Signed-off-by: Tonis Tiigi <[email protected]>
  • Loading branch information
dmcgowan authored and tonistiigi committed Jun 19, 2017
1 parent d3c69bc commit fa82d4b
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions identity/randomid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package identity

import (
cryptorand "crypto/rand"
"fmt"
"io"
"math/big"
)

var (
// idReader is used for random id generation. This declaration allows us to
// replace it for testing.
idReader = cryptorand.Reader
)

// parameters for random identifier generation. We can tweak this when there is
// time for further analysis.
const (
randomIDEntropyBytes = 17
randomIDBase = 36

// To ensure that all identifiers are fixed length, we make sure they
// get padded out or truncated to 25 characters.
//
// For academics, f5lxx1zz5pnorynqglhzmsp33 == 2^128 - 1. This value
// was calculated from floor(log(2^128-1, 36)) + 1.
//
// While 128 bits is the largest whole-byte size that fits into 25
// base-36 characters, we generate an extra byte of entropy to fill
// in the high bits, which would otherwise be 0. This gives us a more
// even distribution of the first character.
//
// See http://mathworld.wolfram.com/NumberLength.html for more information.
maxRandomIDLength = 25
)

// NewID generates a new identifier for use where random identifiers with low
// collision probability are required.
//
// With the parameters in this package, the generated identifier will provide
// ~129 bits of entropy encoded with base36. Leading padding is added if the
// string is less 25 bytes. We do not intend to maintain this interface, so
// identifiers should be treated opaquely.
func NewID() string {
var p [randomIDEntropyBytes]byte

if _, err := io.ReadFull(idReader, p[:]); err != nil {
panic(fmt.Errorf("failed to read random bytes: %v", err))
}

p[0] |= 0x80 // set high bit to avoid the need for padding
return (&big.Int{}).SetBytes(p[:]).Text(randomIDBase)[1 : maxRandomIDLength+1]
}

0 comments on commit fa82d4b

Please sign in to comment.