diff --git a/random.go b/random.go index 0ef88f2..5ac5896 100644 --- a/random.go +++ b/random.go @@ -18,6 +18,9 @@ const ( letterIdxMax = 63 / letterIdxBits ) +// maxInt32 is the maximum positive value for a int32 number type +const maxInt32 = 2147483647 + var ( // ErrInvalidLength is returned if the provided maximum number is equal or less than zero ErrInvalidLength = errors.New("provided length value cannot be zero or less") @@ -58,80 +61,80 @@ func (g *Generator) GetPasswordLength() (int64, error) { if g.config.FixedLength > 0 { return g.config.FixedLength, nil } - mil := g.config.MinLength - mal := g.config.MaxLength - if mil > mal { - mal = mil + minLength := g.config.MinLength + maxLength := g.config.MaxLength + if minLength > maxLength { + maxLength = minLength } - diff := mal - mil + 1 - ra, err := g.RandNum(diff) + diff := maxLength - minLength + 1 + randNum, err := g.RandNum(diff) if err != nil { return 0, err } - l := mil + ra - if l <= 0 { + length := minLength + randNum + if length <= 0 { return 1, nil } - return l, nil + return length, nil } -// RandomBytes returns a byte slice of random bytes with length n that got generated by +// RandomBytes returns a byte slice of random bytes with given length that got generated by // the crypto/rand generator -func (g *Generator) RandomBytes(n int64) ([]byte, error) { - if n < 1 { +func (g *Generator) RandomBytes(length int64) ([]byte, error) { + if length < 1 { return nil, ErrInvalidLength } - b := make([]byte, n) - l, err := rand.Read(b) - if int64(l) != n { + bytes := make([]byte, length) + numBytes, err := rand.Read(bytes) + if int64(numBytes) != length { return nil, ErrLengthMismatch } if err != nil { return nil, err } - return b, nil + return bytes, nil } // RandNum generates a random, non-negative number with given maximum value -func (g *Generator) RandNum(m int64) (int64, error) { - if m < 1 { +func (g *Generator) RandNum(max int64) (int64, error) { + if max < 1 { return 0, ErrInvalidLength } - mbi := big.NewInt(m) - rn, err := rand.Int(rand.Reader, mbi) + max64 := big.NewInt(max) + randNum, err := rand.Int(rand.Reader, max64) if err != nil { return 0, fmt.Errorf("random number generation failed: %w", err) } - return rn.Int64(), nil + return randNum.Int64(), nil } // RandomStringFromCharRange returns a random string of length l based of the range of characters given. // The method makes use of the crypto/random package and therfore is // cryptographically secure -func (g *Generator) RandomStringFromCharRange(l int64, cr string) (string, error) { - if l < 1 { +func (g *Generator) RandomStringFromCharRange(length int64, charRange string) (string, error) { + if length < 1 { return "", ErrInvalidLength } - if len(cr) < 1 { + if len(charRange) < 1 { return "", ErrInvalidCharRange } rs := strings.Builder{} // As long as the length is smaller than the max. int32 value let's grow // the string builder to the actual size, so we need less allocations - if l <= 2147483647 { - rs.Grow(int(l)) + if length <= maxInt32 { + rs.Grow(int(length)) } - crl := len(cr) + charRangeLength := len(charRange) rp := make([]byte, 8) _, err := rand.Read(rp) if err != nil { return rs.String(), err } - for i, c, r := l-1, binary.BigEndian.Uint64(rp), letterIdxMax; i >= 0; { + for i, c, r := length-1, binary.BigEndian.Uint64(rp), letterIdxMax; i >= 0; { if r == 0 { _, err = rand.Read(rp) if err != nil { @@ -139,8 +142,8 @@ func (g *Generator) RandomStringFromCharRange(l int64, cr string) (string, error } c, r = binary.BigEndian.Uint64(rp), letterIdxMax } - if idx := int(c & letterIdxMask); idx < crl { - rs.WriteByte(cr[idx]) + if idx := int(c & letterIdxMask); idx < charRangeLength { + rs.WriteByte(charRange[idx]) i-- } c >>= letterIdxBits