1
0
mirror of https://github.com/Luzifer/password.git synced 2024-09-19 18:32:57 +00:00
password/lib/xkcd.go
Knut Ahlers 83660a3cdf
Update dependencies, replace usage of fmt.Errorf
Signed-off-by: Knut Ahlers <knut@ahlers.me>
2022-06-27 19:45:12 +02:00

63 lines
1.4 KiB
Go

package securepassword
import (
"strings"
"time"
"github.com/pkg/errors"
"github.com/Luzifer/go_helpers/v2/str"
)
type XKCD struct {
// Separator to be used between words
Separator string
}
var (
// ErrTooFewWords represents an error thrown if the password will
// have fewer than four words and are not considered to be safe
ErrTooFewWords = errors.New("XKCD passwords with less than 4 words makes no sense")
// DefaultXKCD contains an default instance of the XKCD password
// generator
DefaultXKCD = NewXKCDGenerator()
)
// NewXKCDGenerator initializes a new XKCD password generator
// https://xkcd.com/936/
func NewXKCDGenerator() *XKCD { return &XKCD{} }
// GeneratePassword generates a password with the number of words
// given and optionally the current date prepended
func (x XKCD) GeneratePassword(length int, addDate bool) (string, error) {
if length < minPasswordLength {
return "", ErrTooFewWords
}
var (
password string
usedWords []string
)
if addDate {
password = time.Now().Format("20060102.")
}
for len(usedWords) < length {
widx, err := randIntn(len(xkcdWordList))
if err != nil {
return "", errors.Wrap(err, "generating random number")
}
word := strings.Title(xkcdWordList[widx])
if str.StringInSlice(word, usedWords) {
// Don't use a word twice
continue
}
usedWords = append(usedWords, word)
}
return password + strings.Join(usedWords, x.Separator), nil
}