view misc/random.go @ 339:33b59c848771

Factored out some miscellaneous code into own package.
author Sascha L. Teichmann <teichmann@intevation.de>
date Sun, 05 Aug 2018 15:35:29 +0200
parents
children
line wrap: on
line source

package misc

import (
	"bytes"
	"crypto/rand"
	"io"
	"log"
	"math/big"
)

func GenerateRandomKey(length int) []byte {
	k := make([]byte, length)
	if _, err := io.ReadFull(rand.Reader, k); err != nil {
		return nil
	}
	return k
}

func RandomString(n int) string {

	const (
		special  = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
		alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
			"abcdefghijklmnopqrstuvwxyz" +
			"0123456789" +
			special
	)

	max := big.NewInt(int64(len(alphabet)))
	out := make([]byte, n)

	for i := 0; i < 1000; i++ {
		for i := range out {
			v, err := rand.Int(rand.Reader, max)
			if err != nil {
				log.Panicf("error: %v\n", err)
			}
			out[i] = alphabet[v.Int64()]
		}
		// Ensure at least one special char.
		if bytes.IndexAny(out, special) >= 0 {
			return string(out)
		}
	}
	log.Println("warn: Your random generator may be broken.")
	out[0] = special[0]
	return string(out)
}