before adding cryptoshuffler
This commit is contained in:
@@ -1,12 +1,37 @@
|
||||
package pwgenerator
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
GetCharset returns a CharSet from a set of characters.
|
||||
|
||||
chars can be one of []rune, []byte, []string, or string.
|
||||
*/
|
||||
func GetCharset(chars interface{}) (charset CharSet, err error) {
|
||||
|
||||
switch t := chars.(type) {
|
||||
case []rune:
|
||||
charset = CharSet(string(t))
|
||||
case []byte:
|
||||
charset = CharSet(string(t))
|
||||
case []string:
|
||||
s := strings.Join(t, "")
|
||||
charset = CharSet(s)
|
||||
case string:
|
||||
charset = CharSet(t)
|
||||
default:
|
||||
err = ErrBadType
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// sortDedupe sorts a slice of runes and deduplicates them.
|
||||
func sortDedupe(charset *CharSet) {
|
||||
|
||||
@@ -42,12 +67,16 @@ func sortDedupe(charset *CharSet) {
|
||||
*/
|
||||
func saferRandInt(max int) (randInt int, err error) {
|
||||
|
||||
// Avoid a panic on max being 0 per rand.Int.
|
||||
if max == 0 {
|
||||
max = 1
|
||||
}
|
||||
|
||||
var max64 int64 = int64(max)
|
||||
var cryptoInt *big.Int = big.NewInt(max64)
|
||||
var cryptoReader *bytes.Buffer = new(bytes.Buffer)
|
||||
var randInt64 int64
|
||||
|
||||
if cryptoInt, err = rand.Int(cryptoReader, cryptoInt); err != nil {
|
||||
if cryptoInt, err = rand.Int(rand.Reader, cryptoInt); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
package pwgenerator
|
||||
|
||||
/*
|
||||
Has returns true if a CharSet contains char.
|
||||
|
||||
char can be one of: Char, byte, rune, or a string (of length 1).
|
||||
*/
|
||||
func (c *CharSet) Has(char interface{}) (contains bool, err error) {
|
||||
|
||||
var chkChar Char
|
||||
|
||||
switch t := char.(type) {
|
||||
case Char:
|
||||
chkChar = t
|
||||
case byte:
|
||||
chkChar = Char(t)
|
||||
case rune:
|
||||
chkChar = Char(t)
|
||||
case string:
|
||||
if len(t) != 1 {
|
||||
err = ErrBadType
|
||||
return
|
||||
}
|
||||
chkChar = Char(t[0])
|
||||
default:
|
||||
err = ErrBadType
|
||||
return
|
||||
}
|
||||
|
||||
for _, i := range *c {
|
||||
if chkChar == i {
|
||||
contains = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Len returns the length of a CharSet (needed for sort.Interface).
|
||||
func (c *CharSet) Len() (l int) {
|
||||
|
||||
@@ -23,7 +60,7 @@ func (c *CharSet) RandChar() (char Char, err error) {
|
||||
|
||||
var selectIdx int
|
||||
|
||||
if selectIdx, err = saferRandInt(len(*c) - 1); err != nil {
|
||||
if selectIdx, err = saferRandInt(len(*c)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -71,14 +71,23 @@ func (o *GenOpts) generatePassword(c CharSet) (password string, err error) {
|
||||
// And make the rune slice of that length.
|
||||
passAlloc = make([]rune, passLen)
|
||||
|
||||
for _, idx := range passAlloc {
|
||||
for idx, _ := range passAlloc {
|
||||
var char Char
|
||||
|
||||
if char, err = c.RandChar(); err != nil {
|
||||
return
|
||||
}
|
||||
for {
|
||||
var isDisabled bool
|
||||
|
||||
passAlloc[idx] = rune(char)
|
||||
if char, err = c.RandChar(); err != nil {
|
||||
return
|
||||
}
|
||||
if isDisabled, err = o.DisabledChars.Has(char); err != nil || isDisabled {
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
|
||||
passAlloc[idx] = rune(char)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
password = string(passAlloc)
|
||||
|
||||
Reference in New Issue
Block a user