| 
					
				 | 
			
			
				@@ -3,11 +3,10 @@ package main 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"flag" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"fmt" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	"github.com/trustelem/zxcvbn" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"math" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"os" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	"passphrase-entropy/packages/haveibeenpwned" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	"strings" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"github.com/trustelem/zxcvbn" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"github.com/chaosbunker/haveibeenpwned" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func contains(arr [3]string, str string) bool { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -19,15 +18,7 @@ func contains(arr [3]string, str string) bool { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func myUsage() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	fmt.Println("usage: passphrase-strength <command> [<args>]") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	fmt.Println("Available commands are: ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	fmt.Println(" diceware   Calculate strength of a diceware passphrase") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	fmt.Println(" random     Calculate strength of a random string") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	fmt.Println(" invented   Calculate strength of an invented passphrase") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func secondsToHuman(guesses float64) (result string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func guessesToHuman(guesses float64) (result string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	minute := float64(60) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	hour := minute * 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	day := hour * 24 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -41,53 +32,62 @@ func secondsToHuman(guesses float64) (result string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 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))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		result = fmt.Sprintf("%d hours  ", int(math.Round(guesses / hour))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} else if guesses < month { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		result = fmt.Sprintf("%d days", int(math.Round(guesses / day))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		result = fmt.Sprintf("%d days   ", int(math.Round(guesses / day))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} else if guesses < year { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		result = fmt.Sprintf("%d months", int(math.Round(guesses / month))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		result = fmt.Sprintf("%d months ", int(math.Round(guesses / month))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} else if guesses < century { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		result = fmt.Sprintf("%d years", int(math.Round(guesses / year))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		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 passphrase, words string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var password string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var pwnedFlag, haveIBeenPwned bool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var words arrayFlags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var err error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	flag.StringVar(&passphrase,"password", "", "the password") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	flag.StringVar(&words, "words", "", "used words") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	flag.BoolVar(&pwnedFlag, "pwned", false, "check if password has been seen before") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	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 || passphrase == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if len(os.Args) == 1 || password == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		flag.PrintDefaults() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if pwnedFlag == true { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		haveIBeenPwned, err = pwned.IsPasswordCompromised(passphrase) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		haveIBeenPwned, err = pwned.IsPasswordCompromised(password) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		fmt.Println(haveIBeenPwned) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		fmt.Println("Something went wrong.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		userInput := strings.Fields(words) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		strength := zxcvbn.PasswordStrength(passphrase, userInput) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		strength := zxcvbn.PasswordStrength(password, words) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		guesses := strength.Guesses 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		fmt.Printf("\nPassword:\t\t%s\n", passphrase) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		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(float64(guesses))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		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",secondsToHuman(guesses * (3600 / 100))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		fmt.Printf("10  / s:\t\t%s\t(unthrottled online attack)\n",secondsToHuman(guesses/10)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		fmt.Printf("10k / s:\t\t%s\t(offline attack, slow hash, many cores)\n",secondsToHuman(guesses / 1e4)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		fmt.Printf("10b / s:\t\t%s\t(offline attack, slow hash, many cores)\n",secondsToHuman(guesses / 1e10)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		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, slow hash, many cores)\n", guessesToHuman(guesses / 1e10)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if haveIBeenPwned == true { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		fmt.Println("\nThis password has been compromised and should not be used.") 
			 |