ooni-probe-cli/internal/randx/randx.go

60 lines
1.8 KiB
Go

// Package randx contains math/rand extensions. The functions
// exported by this package do not use a CSRNG so you SHOULD NOT
// use these strings for, e.g., generating passwords.
package randx
import (
"math/rand"
"time"
"unicode"
)
// These constants are used by lettersWithString.
const (
uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lowercase = "abcdefghijklmnopqrstuvwxyz"
letters = uppercase + lowercase
)
// lettersWithString is a method for generating a random string
// described at https://stackoverflow.com/questions/22892120.
func lettersWithString(n int, letterBytes string) string {
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rnd.Intn(len(letterBytes))]
}
return string(b)
}
// Letters return a string composed of random letters. Note that
// this function uses a non-cryptographically-secure generator.
func Letters(n int) string {
return lettersWithString(n, letters)
}
// LettersUppercase return a string composed of random uppercase
// letters. Note that this function uses a non-cryptographically-secure
// generator. So, we SHOULD NOT use it for generating passwords.
func LettersUppercase(n int) string {
return lettersWithString(n, uppercase)
}
// ChangeCapitalization returns a new string where the capitalization
// of each character is changed at random. Note that this function
// uses a non-cryptographically-secure generator. So, we SHOULD NOT use
// it for generating passwords.
func ChangeCapitalization(source string) (dest string) {
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
for _, chr := range source {
if unicode.IsLower(chr) && rnd.Float64() <= 0.5 {
dest += string(unicode.ToUpper(chr))
} else if unicode.IsUpper(chr) && rnd.Float64() <= 0.5 {
dest += string(unicode.ToLower(chr))
} else {
dest += string(chr)
}
}
return
}