go

Go, create a Unicode random string generator
🥺😂🥰😊😍😊😝🤗abcdefghijklmnopqrstuvwxyz

Reading time of 517 words
3 minutes
Reading time of 517 words ~ 3 minutes


Did you find this article helpful?
Please consider tipping me a coffee as a thank you.
Ko-fi Buy Me a Coffee
Did you find this article helpful? Please consider tipping me a coffee or three as a thank you.
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

Did you find this article helpful?
Please consider tipping me a coffee as a thank you.
Ko-fi Buy Me a Coffee
Did you find this article helpful? Please consider tipping me a coffee or three as a thank you.
Tip using Ko-fi or Buy Me a Coffee