package apg import ( "crypto/rand" "encoding/binary" "errors" "fmt" "math/big" "strings" ) const ( // 7 bits to represent a letter index letterIdxBits = 7 // All 1-bits, as many as letterIdxBits letterIdxMask = 1<= 0; { if r == 0 { _, err = rand.Read(rp) if err != nil { return rs.String(), err } c, r = binary.BigEndian.Uint64(rp), letterIdxMax } if idx := int(c & letterIdxMask); idx < crl { rs.WriteByte(cr[idx]) i-- } c >>= letterIdxBits r-- } return rs.String(), nil } // RandNum generates a random, non-negative number with given maximum value func (g *Generator) RandNum(m int64) (int64, error) { if m < 1 { return 0, ErrInvalidLength } mbi := big.NewInt(m) rn, err := rand.Int(rand.Reader, mbi) if err != nil { return 0, fmt.Errorf("random number generation failed: %w", err) } return rn.Int64(), nil } // CoinFlip performs a simple coinflip based on the rand library and returns 1 or 0 func (g *Generator) CoinFlip() int64 { cf, _ := g.RandNum(2) return cf } // CoinFlipBool performs a simple coinflip based on the rand library and returns true or false func (g *Generator) CoinFlipBool() bool { return g.CoinFlip() == 1 }