package main import ( "flag" "fmt" "github.com/chaosbunker/haveibeenpwned" "github.com/trustelem/zxcvbn" "math" "os" ) func contains(arr [3]string, str string) bool { for _, a := range arr { if a == str { return true } } return false } func guessesToHuman(guesses float64) (result string) { minute := float64(60) hour := minute * 60 day := hour * 24 month := day * 31 year := month * 12 century := year * 100 if guesses < 1 { result = "< 1 second" } else if guesses < minute { result = fmt.Sprintf("%d seconds", int(math.Round(guesses))) } else if guesses < hour { result = fmt.Sprintf("%d minutes", int(math.Round(guesses / minute))) } else if guesses < day { result = fmt.Sprintf("%d hours ", int(math.Round(guesses / hour))) } else if guesses < month { result = fmt.Sprintf("%d days ", int(math.Round(guesses / day))) } else if guesses < year { result = fmt.Sprintf("%d months ", int(math.Round(guesses / month))) } else if guesses < century { result = fmt.Sprintf("%d years ", int(math.Round(guesses / year))) } else { result = fmt.Sprintf("Centuries") } return } type arrayFlags []string func (i *arrayFlags) String() string { return "my string representation" } func (i *arrayFlags) Set(value string) error { *i = append(*i, value) return nil } func main() { var password string var pwnedFlag, haveIBeenPwned bool var words arrayFlags var err error flag.StringVar(&password,"password", "", "a password") flag.Var(&words, "word", "used words, e.g. -password p4ssw0rd -word password") flag.BoolVar(&pwnedFlag, "pwned", false, "check with haveibeenpwned API if password has been seen before") flag.Parse() if len(os.Args) == 1 || password == "" { flag.PrintDefaults() return } if pwnedFlag == true { haveIBeenPwned, err = pwned.IsPasswordCompromised(password) } if err != nil { fmt.Println("Something went wrong.") } else { strength := zxcvbn.PasswordStrength(password, words) guesses := strength.Guesses fmt.Printf("\nPassword:\t\t%s\n", password) fmt.Printf("Password strength:\t%d/4\n", strength.Score) fmt.Printf("Guesses Log10:\t\t%f\n", math.Log10(guesses)) fmt.Println("\nGuess times") fmt.Printf("100 / h:\t\t%s\t(throttled online attack)\n", guessesToHuman(guesses * (3600 / 100))) fmt.Printf("10 / s:\t\t%s\t(unthrottled online attack)\n", guessesToHuman(guesses / 10)) fmt.Printf("10k / s:\t\t%s\t(offline attack, slow hash, many cores)\n", guessesToHuman(guesses / 1e4)) fmt.Printf("10b / s:\t\t%s\t(offline attack, fast hash, many cores)\n", guessesToHuman(guesses / 1e10)) } if haveIBeenPwned == true { fmt.Println("\nThis password has been compromised and should not be used.") } }