Skip to content

Instantly share code, notes, and snippets.

@imjasonh
Last active October 28, 2021 06:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save imjasonh/8093716 to your computer and use it in GitHub Desktop.
Save imjasonh/8093716 to your computer and use it in GitHub Desktop.
Utility script to generate random strings of a user-defined length from a user-provided alphabet
// Package gibberish provides methods to generate random bytes and strings of random characters.
package gibberish
import (
"bytes"
"io"
"math/rand"
)
type rdr []byte
// NewReader returns a Reader that generates gibberish.
func NewReader(b []byte) io.Reader {
return rdr(b)
}
// Read satisfies io.Reader
func (r rdr) Read(p []byte) (int, error) {
l := len(p)
for i := 0; i < l; i++ {
p[i] = r[rand.Intn(len(r))]
}
return l, nil
}
// NewString returns a string of length l consisting of random bytes selected from b
func NewString(a []byte, l int64) string {
bf := bytes.NewBuffer(make([]byte, l))
io.CopyN(bf, NewReader(a), l)
return string(bf.Bytes())
}
package gibberish
import (
"io"
"io/ioutil"
"testing"
)
/* Sample results
BenchmarkNewString_10 1000000 1407 ns/op
BenchmarkNewString_100 500000 6312 ns/op
BenchmarkNewString_1000 50000 40865 ns/op
BenchmarkNewString_10000 5000 401077 ns/op
BenchmarkNewString_100000 500 3867688 ns/op
BenchmarkReader 50 38504878 ns/op 27.23 MB/s
*/
var alphabet = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_")
func bench(b *testing.B, n int64) {
for i := 0; i < b.N; i++ {
NewString(alphabet, n)
}
}
func BenchmarkNewString_10(b *testing.B) { bench(b, int64(10)) }
func BenchmarkNewString_100(b *testing.B) { bench(b, int64(100)) }
func BenchmarkNewString_1000(b *testing.B) { bench(b, int64(1000)) }
func BenchmarkNewString_10000(b *testing.B) { bench(b, int64(10000)) }
func BenchmarkNewString_100000(b *testing.B) { bench(b, int64(100000)) }
const toCopy = 1024 * 1024
func BenchmarkReader(b *testing.B) {
b.SetBytes(toCopy)
r := NewReader(alphabet)
b.ResetTimer()
for i := 0; i < b.N; i++ {
io.CopyN(ioutil.Discard, r, toCopy)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment