Logo

Programming-Idioms

  • Lisp
  • Go

Idiom #317 Random string

Create a string s of n characters having uniform random values out of the 62 alphanumeric values A-Z, a-z, 0-9

import "math/rand"
var alphanum = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")

func randomString(n int, rng *rand.Rand) string {
	a := make([]rune, n)
	for i := range a {
		a[i] = alphanum[rng.Intn(len(alphanum))]
	}
	return string(a)
}

This version is slightly more generic: it works with an alphabet of arbitrary runes, which don't need to fit in a single byte each.

Note that the package math/rand is not crypto-secure.
import "math/rand"
const alphanum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

func randomString(n int, rng *rand.Rand) string {
	a := make([]byte, n)
	for i := range a {
		a[i] = alphanum[rng.Intn(len(alphanum))]
	}
	return string(a)
}

Using a custom rand.Rand instance lets you control the seed, and is also better for performance (lock-free).
Note that the package math/rand is not crypto-secure.
import "math/rand"
const alphanum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

func randomString(n int) string {
	a := make([]byte, n)
	for i := range a {
		a[i] = alphanum[rand.Intn(len(alphanum))]
	}
	return string(a)
}

Each of these runes fits in a single byte.
The default RNG can be run concurrently, as it incurs the cost of a Mutex.
Note that the package math/rand is not crypto-secure
const s = ((n) => {
    const alphanum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    let s = "";
    for (let i = 0; i < n; i += 1) {
        s += alphanum[~~(Math.random() * alphanum.length)];
    }
    return s;
})(n);

~~ is a faster way to call Math.floor().

Note that Math.random is not cryptographically secure.

New implementation...