Skip to content

Commit

Permalink
Rewrite Cryptographically Secure RandomString Function
Browse files Browse the repository at this point in the history
- Avoid big package
- Use strings.Builder for efficient string concatenation
- Set default string length to 10
- Handle errors from rand.Read()

Resolves: #487
  • Loading branch information
ealvar3z committed Sep 14, 2023
1 parent 57a4fb4 commit bd1bb20
Showing 1 changed file with 30 additions and 22 deletions.
52 changes: 30 additions & 22 deletions internal/test/random.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,42 @@ package test

import (
"crypto/rand"
"math/big"
"strings"
)

var (
strLen = 10
//nolint:gomnd // this avoids the golangci-lint "magic number" warning
n = big.NewInt(2)
)
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const strLen = 10

// RandomString generates a cryptographically secure random string of a fixed
// length. The string is composed of alphanumeric characters and is generated
// using the crypto/rand library. The length of the string is determined by the
// constant strLen.
// See StackOverflow answer:
// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go
// RandomString generates a cryptographically secure random string of length
// strLen.
func RandomString() string {
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
s := make([]rune, strLen)
max := big.NewInt(int64(len(letters)))
for i := range s {
randomInt, _ := rand.Int(rand.Reader, max)
s[i] = letters[randomInt.Int64()]
sb := strings.Builder{}
sb.Grow(strLen)

for i := 0; i < strLen; i++ {
randomByte := make([]byte, 1)
_, err := rand.Read(randomByte)
if err != nil {
return ""
}
randomIndex := randomByte[0] % byte(len(letters))
sb.WriteByte(letters[randomIndex])
}
return string(s)

return sb.String()
}

// RandomBool generates a cryptographically secure random boolean value. It
// uses the crypto/rand library to generate a random integer (either 0 or 1),
// and returns true if the integer is 1, and false otherwise.
// RandomBool generates a cryptographically secure random boolean value.
// It reads a single byte from the crypto/rand library and uses its least
// significant bit to determine the boolean value. The function returns
// true if the least significant bit is 1, and false otherwise.
func RandomBool() bool {
randomInt, _ := rand.Int(rand.Reader, n)
return randomInt.Int64() == 1
var b [1]byte
_, err := rand.Read(b[:])
if err != nil {
return false
}
return b[0]&1 == 1
}

0 comments on commit bd1bb20

Please sign in to comment.