71 lines · 1.8 KB · Go
RawDownload
// Package random holds a few functions for working with random numberspackage random import (	cryptorand "crypto/rand"	"encoding/base64"	"encoding/binary"	mathrand "math/rand" 	"github.com/pkg/errors") // String create a random string for test purposes.//// Do not use these for passwords.func String(n int) string {	const (		vowel     = "aeiou"		consonant = "bcdfghjklmnpqrstvwxyz"		digit     = "0123456789"	)	pattern := []string{consonant, vowel, consonant, vowel, consonant, vowel, consonant, digit}	out := make([]byte, n)	p := 0	for i := range out {		source := pattern[p]		p = (p + 1) % len(pattern)		out[i] = source[mathrand.Intn(len(source))]	}	return string(out)} // Password creates a crypto strong password which is just about// memorable.  The password is composed of printable ASCII characters// from the base64 alphabet.//// Requires password strength in bits.// 64 is just about memorable// 128 is securefunc Password(bits int) (password string, err error) {	bytes := bits / 8	if bits%8 != 0 {		bytes++	}	var pw = make([]byte, bytes)	n, err := cryptorand.Read(pw)	if err != nil {		return "", errors.Wrap(err, "password read failed")	}	if n != bytes {		return "", errors.Errorf("password short read: %d", n)	}	password = base64.RawURLEncoding.EncodeToString(pw)	return password, nil} // Seed the global math/rand with crypto strong data//// This doesn't make it OK to use math/rand in crypto sensitive// environments - don't do that! However it does help to mitigate the// problem if that happens accidentally. This would have helped with// CVE-2020-28924 - #4783func Seed() error {	var seed int64	err := binary.Read(cryptorand.Reader, binary.LittleEndian, &seed)	if err != nil {		return errors.Wrap(err, "failed to read random seed")	}	mathrand.Seed(seed)	return nil}