Golang generate random string Examples [SOLVED]


GOLANG Solutions, GO

Author: Tuan Nguyen
Reviewer: Deepak Prasad

We may desire to generate random strings or even sets of characters in order to perform some operations with strings in an application. We can choose a character at random from a set of characters, change the order of characters in a given string, or generate a random string. In Golang, with the help of the rand package, we can easily write a custom function to generate a random string with the desired length.

 

Using rand function

Package rand implements pseudo-random number generators unsuitable for security-sensitive work.

Random numbers are generated by a Source. Top-level functions, such as Float64 and Int, use a default shared Source that produces a deterministic sequence of values each time a program is run. Use the Seed function to initialize the default Source if different behavior is required for each run. The default Source is safe for concurrent use by multiple goroutines, but Sources created by NewSource are not.

This package's outputs might be easily predictable regardless of how it's seeded. For random numbers suitable for security-sensitive work, see the crypto/rand package.

For example, in the below example rand.Intn returns a random int n, 0 <= n < 100

package main

import (
	"fmt"
	"math/rand"
)

func main() {
	fmt.Print("Random number: ", rand.Intn(100))
}

Output:

Random number: 81

 

Method-1: Generate random string from pre-defined characters

The ideal is we randomly select characters from a given charset as many times as the set length of the output and combine them to form a random.

package main

import (
	"fmt"
	"math/rand"
	"time"
)

// define the given charset, char only
var charset = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

// n is the length of random string we want to generate
func randStr(n int) string {
	b := make([]byte, n)
	for i := range b {
		// randomly select 1 character from given charset
		b[i] = charset[rand.Intn(len(charset))]
	}
	return string(b)
}

func main() {
	// Seeding with the same value results in the same random sequence each run.
	// For different numbers, seed with a different value, such as
	// time.Now().UnixNano(), which yields a constantly-changing number.
	rand.Seed(time.Now().UnixNano())

	fmt.Println("First random string: ", randStr(10))
	fmt.Println("Second random string: ", randStr(10))
	fmt.Println("Third random string: ", randStr(20))
}

Output:

First random string:  DpJdqMraoi
Second random string:  HwfENfgprn
Third random string:  APSsUQJNnVbXDbDuilpr

Explanation: Create a charset to define which characters will be in the string. Create a byte list to contains all the characters of the string. In the for loop, we generate the n (size of the output string) random characters and add them to the list. Selecting random characters is done by the rand.Intn() function, which returns a random number between 0 and the length of the charset, then get a character from the charset at this random index. Do this n times and add to the result gives us a list contain n random character. Convert list of bytes to a string

NOTE:
If the characters to choose from and assemble the random string contains only the uppercase and lowercase letters of the English alphabet, we can work with bytes only because the English alphabet letters map to bytes 1-to-1 in the UTF-8 encoding (which is how Go stores strings).

So instead of:

var charset = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

we can use:

const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

 

Method-2: Generate random string using rand.Read()

Read is a helper function that calls Reader with syntax func Read(b []byte) (n int, err error). This example reads 10 cryptographically secure pseudorandom numbers from rand.Reader and writes them to a byte slice.

c := 10
b := make([]byte, c)
_, err := rand.Read(b)

For example:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func randStr(length int) string {
	rand.Seed(time.Now().UnixNano())
	b := make([]byte, length)
	// Read b number of numbers
	rand.Read(b)
	return fmt.Sprintf("%x", b)[:length]
}

func main() {
	fmt.Println("First random string of fixed length: ", randStr(10))
	fmt.Println("Second random string of fixed length: ", randStr(15))
	fmt.Println("Third random string of fixed length: ", randStr(20))
}

Output:

First random string of fixed length:  0c204d3960
Second random string of fixed length:  0c204d39600fddd
Third random string of fixed length:  0c204d39600fddd3f1f2

 

Example-1: Generate random string with integers only

In this example we will generate random string containing numbers only:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

// define the given charset, char only
var number = []byte("0123456789")

// n is the length of random string we want to generate
func randStr(n int) string {
	b := make([]byte, n)
	for i := range b {
		// randomly select 1 character from given charset
		b[i] = number[rand.Intn(len(number))]
	}
	return string(b)
}

func main() {
	// Seeding with the same value results in the same random sequence each run.
	// For different numbers, seed with a different value, such as
	// time.Now().UnixNano(), which yields a constantly-changing number.
	rand.Seed(time.Now().UnixNano())

	fmt.Println("Time run: ", time.Now().UnixNano())
	fmt.Println("First random string: ", randStr(10))
	fmt.Println("Second random string: ", randStr(10))
	fmt.Println("Third random string: ", randStr(20))
}

Output:

Time run:  1663523354636371100
First random string:  7875183419
Second random string:  2768545022
Third random string:  47681351755701582659

 

Example-2: Generate random string with alphanumeric characters only

As discussed, we have to modify the byte list to meet the requirement:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

// define the given charset, char only
var charset = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
var number = []byte("0123456789")
var alphaNumeric = append(charset, number...)

// n is the length of random string we want to generate
func randStr(n int) string {
	b := make([]byte, n)
	for i := range b {
		// randomly select 1 character from given charset
		b[i] = alphaNumeric[rand.Intn(len(alphaNumeric))]
	}
	return string(b)
}

func main() {
	// Seeding with the same value results in the same random sequence each run.
	// For different numbers, seed with a different value, such as
	// time.Now().UnixNano(), which yields a constantly-changing number.
	rand.Seed(time.Now().UnixNano())

	fmt.Println("Time run: ", time.Now().UnixNano())
	fmt.Println("First random string: ", randStr(10))
	fmt.Println("Second random string: ", randStr(10))
	fmt.Println("Third random string: ", randStr(20))
}

Output:

Time run:  1663523245039802700
First random string:  P3nG59rlng
Second random string:  8A9MU4aahB
Third random string:  Frgfp92JbulJhHUbhdMM

 

Example-3: Pre-define custom requirement for random string

In this example we will select 1 uppercase, 1 lowercase, 1 number and 1 special character and randomly choose the remaining characters. After that, we will shuffle the order of bytes and return the string.

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func randStr() string {
	var lower = []byte("abcdefghijklmnopqrstuvwxyz")
	var upper = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
	var number = []byte("0123456789")
	var special = []byte("~=+%^*/()[]{}/!@#$?|")
	allChar := append(lower, upper...)
	allChar = append(allChar, number...)
	allChar = append(allChar, special...)

	b := make([]byte, 12)
	// select 1 upper, 1 lower, 1 number and 1 special
	b[0] = lower[rand.Intn(len(lower))]
	b[1] = upper[rand.Intn(len(upper))]
	b[2] = number[rand.Intn(len(number))]
	b[3] = special[rand.Intn(len(special))]
	for i := 4; i < 12; i++ {
		// randomly select 1 character from given charset
		b[i] = allChar[rand.Intn(len(allChar))]
	}

	//shuffle character
	rand.Shuffle(len(b), func(i, j int) {
		b[i], b[j] = b[j], b[i]
	})

	return string(b)
}

func main() {
	// Seeding with the same value results in the same random sequence each run.
	// For different numbers, seed with a different value, such as
	// time.Now().UnixNano(), which yields a constantly-changing number.
	rand.Seed(time.Now().UnixNano())

	fmt.Println("Time run: ", time.Now().UnixNano())
	fmt.Println("First random string: ", randStr())
	fmt.Println("Second random string: ", randStr())
	fmt.Println("Third random string: ", randStr())
}

Output:

PS C:\Users\admin\Desktop\golang\src\main> go run .\milestone15.go
Time run:  1663524606744377000
First random string:  avr[oa4X^(2B
Second random string:  2/7EB?5trI/z
Third random string:  k(vGv3$P+RgF

PS C:\Users\admin\Desktop\golang\src\main> go run .\milestone15.go
Time run:  1663524610066538700
First random string:  z7I#1UkZeyCz
Second random string:  Vk0+5[H|2]C1
Third random string:  96E/4]dNDHDb

 

Summary

In this article, I demonstrated how to use the math.rand() function to generate a random string of any length. If you want to limit or add new characters to the set from which the random string is made, modify the charset variable.

 

References

https://pkg.go.dev/math/rand
https://pkg.go.dev/time#Time.UnixNano
https://pkg.go.dev/crypto/rand#Read
How to generate a random string of a fixed length in Go?

 

Tuan Nguyen

Tuan Nguyen

He is proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment