package main import ( "flag" "fmt" "math" "os" "strings" ) func contains(arr [3]string, str string) bool { for _, a := range arr { if a == str { return true } } return false } func myUsage() { fmt.Println("usage: passphrase-entropy []") fmt.Println("Available commands are: ") fmt.Println(" diceware Calculate entropy of a diceware passphrase") fmt.Println(" random Calculate entropy of a random string") fmt.Println(" insecure Calculate entropy of an invented passphrase") } func main() { var charsets map[string]string var usedCharsets[] string var possibleSymbols int = 0 charsets = make(map[string]string) charsets["Numbers"] = "0123456789" charsets["Lowercase"] = "abcdefghijklmnopqrstuvwxyz" charsets["Uppercase"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" charsets["Common Special Characters"] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" charsets["Space"] = " " charsets["Extended ASCII"] = "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" dicewareCommand := flag.NewFlagSet("diceware", flag.ExitOnError) dicewarePassphraseFlag := dicewareCommand.String("passphrase", "", "the passphrase") wordsFlag := dicewareCommand.Int("words", 0, "number of words in passphrase") dictSizeFlag := dicewareCommand.Int("dictSize", 0, "number of words in dictionary") randomCommand := flag.NewFlagSet("random", flag.ExitOnError) randomPassphraseFlag := randomCommand.String("password", "", "the password") insecureCommand := flag.NewFlagSet("insecure", flag.ExitOnError) insecureWords := insecureCommand.Int("words", 0, "number of words in invented passphrase") if len(os.Args) == 1 { myUsage() return } switch os.Args[1] { case "diceware": dicewareCommand.Parse(os.Args[2:]) case "random": randomCommand.Parse(os.Args[2:]) case "insecure": insecureCommand.Parse(os.Args[2:]) default: myUsage() fmt.Printf("\n%q is not valid command.\n", os.Args[1]) os.Exit(2) } if dicewareCommand.Parsed() { if *dicewarePassphraseFlag == "" { dicewareCommand.Usage() return } if *wordsFlag == 0 { dicewareCommand.Usage() return } if *dictSizeFlag == 0 { dicewareCommand.Usage() return } entropy := math.Log2(math.Pow(float64(*dictSizeFlag), float64(*wordsFlag))) fmt.Println("\nPassphrase entropy:", entropy) } if randomCommand.Parsed() { if *randomPassphraseFlag == "" { randomCommand.Usage() return } passphraseLength := len(*randomPassphraseFlag) for key, value := range charsets { if strings.ContainsAny(*randomPassphraseFlag, value) { possibleSymbols += len(value) usedCharsets = append(usedCharsets, key) } } entropy := math.Log2(math.Pow(float64(possibleSymbols), float64(passphraseLength))) fmt.Println("\nNumber of characters:", passphraseLength) fmt.Println("\nUsed character sets:", strings.Join(usedCharsets, ", ")) fmt.Println("\nPassphrase entropy:", entropy) } if insecureCommand.Parsed() { if *insecureWords != 0 { insecureCommand.Usage() return } } }