github.com/argoproj/argo-cd/v3@v3.2.1/util/rand/rand.go (about)

     1  package rand
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"math/big"
     8  )
     9  
    10  const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    11  
    12  // String generates, from the set of capital and lowercase letters, a cryptographically-secure pseudo-random string of a given length.
    13  func String(n int) (string, error) {
    14  	return StringFromCharset(n, letterBytes)
    15  }
    16  
    17  // StringFromCharset generates, from a given charset, a cryptographically-secure pseudo-random string of a given length.
    18  func StringFromCharset(n int, charset string) (string, error) {
    19  	b := make([]byte, n)
    20  	maxIdx := big.NewInt(int64(len(charset)))
    21  	for i := 0; i < n; i++ {
    22  		randIdx, err := rand.Int(rand.Reader, maxIdx)
    23  		if err != nil {
    24  			return "", fmt.Errorf("failed to generate random string: %w", err)
    25  		}
    26  		// randIdx is necessarily safe to convert to int, because the max came from an int.
    27  		randIdxInt := int(randIdx.Int64())
    28  		b[i] = charset[randIdxInt]
    29  	}
    30  	return string(b), nil
    31  }
    32  
    33  // RandHex returns a cryptographically-secure pseudo-random alpha-numeric string of a given length
    34  func RandHex(n int) (string, error) {
    35  	bytes := make([]byte, n/2+1) // we need one extra letter to discard
    36  	if _, err := rand.Read(bytes); err != nil {
    37  		return "", err
    38  	}
    39  	return hex.EncodeToString(bytes)[0:n], nil
    40  }