Go, create a Unicode random string generator
🥺😂🥰😊😍😊😝🤗abcdefghijklmnopqrstuvwxyz
3 minutes
Tip using Ko-fi or Buy Me a Coffee
One of the great things about the Go standard library is how easy it is to create a sophisticated tool using a small amount of code. In this entry, I will explain how to make a variable-length random string generator that can support any Unicode character.
You can find the final result on GitHub or run it at Go Playground.
First, we create a constant containing a collection of Unicode characters that will be used by the randomiser.
const random string = "🥺😂🥰😊😍😊😝🤗abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321 .!?"
The function will require int argument for the length of the returned string and a returned error.
// randString generates a random string of n x characters.
func randString(n int) (string, error) {
return "", nil
}
The s rune slice will contain and return the random characters as a string. Using make we pre-allocate the total number of returned runes (Unicode characters).
s := make([]rune, n)
Convert the random const into a rune array.
r := []rune(random)
Declare the variables.
// randString generates a random string of n x characters.
func randString(n int) (string, error) {
s, r := make([]rune, n), []rune(random)
return "", nil
}
We now loop over the empty rune slice where its index position is the i
variable.
// randString generates a random string of n x characters.
func randString(n int) (string, error) {
s, r := make([]rune, n), []rune(random)
for i := range s {}
return "", nil
}
In each loop iteration, generate a new random big integer using Prime from the crypto/rand library. The library will satisfy any security concerns with gosec or other linters.
// randString generates a random string of n x characters.
func randString(n int) (string, error) {
s, r := make([]rune, n), []rune(random)
for i := range s {
p, err := rand.Prime(rand.Reader, len(r))
if err != nil {
return "", fmt.Errorf("random string n %d: %w", n, err)
}
}
return "", nil
}
Convert the randomly generated big integer into an unsigned 64-bit integer and save it to x
.
x := p.Uint64()
Count the number of random characters and save the result as an unsigned 64-bit integer.
y := uint64(len(r))
Using the modulo operator %
, we find the remainder of x / y
and use that value as the index to fetch a random character from our slice of characters. The fetched character gets appended to our return string until the loop finishes.
// randString generates a random string of n x characters.
func randString(n int) (string, error) {
s, r := make([]rune, n), []rune(random)
for i := range s {
p, err := rand.Prime(rand.Reader, len(r))
if err != nil {
return "", fmt.Errorf("random string n %d: %w", n, err)
}
x, y := p.Uint64(), uint64(len(r))
s[i] = r[x%y]
}
return "", nil
}
If you want to visualise the process, then printf
the variable results within the loop and run it in Go Playground.
fmt.Printf("x: %d y: %d\tx %% y = %d\trandom[%d] = %q\n", x, y, x%y, x%y, string(r[x%y]))
Otherwise, we now have a functional string randomiser.
# 1st go.
p😂H🤗😊JL7😊J9zPD9LFPTB
# 2nd go.
XZff1tzV😂Vx😊bPbvhpV😊
# 3rd go.
fn😂vbF5.FN3XZ😊5Vb😂Z.
Written by Ben Garrett