Golang Random String Generator | srgdev.com

Golang Random String Generator

High performance golang random string generator. The default 'rand.Source' is used, therefore the code is safe for concurrent use by multiple goroutines.Golang, gobench Download: rndstr.go

About

This code is largely based on this StackOverflow answer. The default Source of uniformly-distributed pseudo-random values is seeded at package init() with a time.Now().UnixNano() Returned value can contain any of these 64 characters:

1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_
gobench @see rndstr_test.go:
goos: linux
goarch: amd64
pkg: rndstr
BenchmarkGetBytes48-4     	10000000	 176 ns/op		  48 B/op	1 allocs/op
BenchmarkGetBytes1500-4   	  300000	4863 ns/op		1536 B/op	1 allocs/op
PASS

rndstr.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// A fast random []byte generator. The default Source is used, which // is safe for concurrent use by multiple goroutines. The default Source // is seeded at package init. package rndstr import ( "math/rand" "time" ) func init() { rand.Seed(time.Now().UnixNano()) } const letterBytes = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_" const ( letterIdxBits = 6 // 6 bits to represent a letter index letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits ) // Returns []byte of 'n' length filled with random characters func GetBytes(n int) []byte { b := make([]byte, n) for i, cache, remain := n-1, rand.Int63(), letterIdxMax; i >= 0; { if remain == 0 { cache, remain = rand.Int63(), letterIdxMax } idx := int(cache & letterIdxMask) b[i] = letterBytes[idx] i-- cache >>= letterIdxBits remain-- } return b } // Fills the []byte with random characters func PutBytes(b []byte) { n := len(b) for i, cache, remain := n-1, rand.Int63(), letterIdxMax; i >= 0; { if remain == 0 { cache, remain = rand.Int63(), letterIdxMax } idx := int(cache & letterIdxMask) b[i] = letterBytes[idx] i-- cache >>= letterIdxBits remain-- } }

rndstr_test.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package rndstr import "testing" func TestGetBytes(t *testing.T) { randomBytes := GetBytes(1064) t.Logf("%s", randomBytes) } func TestPutBytes(t *testing.T) { randomBytes := make([]byte, 72) PutBytes(randomBytes) t.Logf("%s", randomBytes) } var result []byte func BenchmarkGetBytes48(b *testing.B) { b.ReportAllocs() var r []byte for n := 0; n < b.N; n++ { r = GetBytes(48) } result = r } func BenchmarkGetBytes1500(b *testing.B) { b.ReportAllocs() var r []byte for n := 0; n < b.N; n++ { r = GetBytes(1500) } result = r }