Mercurial > gemma
view pkg/common/random.go @ 5652:9b3779f649c2 v5.7.1
Bumped version for release.
author | Sascha Wilde <wilde@sha-bang.de> |
---|---|
date | Mon, 07 Aug 2023 17:59:18 +0200 |
parents | 5f47eeea988d |
children |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package common import ( "bytes" "crypto/rand" "io" "math" "math/big" mrand "math/rand" "time" "gemma.intevation.de/gemma/pkg/log" ) // GenerateRandomKey generates a cryptographically secure random key // of a given length. func GenerateRandomKey(length int) []byte { k := make([]byte, length) if _, err := io.ReadFull(rand.Reader, k); err != nil { return nil } return k } // RandomString generates a cryptographically secure password // of a given length which consists of alpha numeric characters // and at least one 'special' one. 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("%v\n", err) } out[i] = alphabet[v.Int64()] } // Ensure at least one special char. if bytes.ContainsAny(out, special) { return string(out) } } log.Warnf("Your random generator may be broken.") out[0] = special[0] return string(out) } // Random returns a function which generates pseudo random // values in the range between low and high. func Random(low, high float64) func() float64 { if low > high { low, high = high, low } var seed int64 if seedInt, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64)); err != nil { log.Warnf("Generating good random seed failed: %v\n", err) seed = time.Now().Unix() } else { seed = seedInt.Int64() } rnd := mrand.New(mrand.NewSource(seed)) m := high - low return func() float64 { return rnd.Float64()*m + low } }