app.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "math"
  6. "os"
  7. "strings"
  8. )
  9. func contains(arr [3]string, str string) bool {
  10. for _, a := range arr {
  11. if a == str {
  12. return true
  13. }
  14. }
  15. return false
  16. }
  17. func myUsage() {
  18. fmt.Println("usage: passphrase-entropy <command> [<args>]")
  19. fmt.Println("Available commands are: ")
  20. fmt.Println(" diceware Calculate entropy of a diceware passphrase")
  21. fmt.Println(" random Calculate entropy of a random string")
  22. fmt.Println(" insecure Calculate entropy of an invented passphrase")
  23. }
  24. func main() {
  25. var charsets map[string]string
  26. var usedCharsets[] string
  27. var possibleSymbols int = 0
  28. var passphrase string
  29. var words int
  30. charsets = make(map[string]string)
  31. charsets["Numbers"] = "0123456789"
  32. charsets["Lowercase"] = "abcdefghijklmnopqrstuvwxyz"
  33. charsets["Uppercase"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  34. charsets["Common Special Characters"] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
  35. charsets["Space"] = " "
  36. charsets["Extended ASCII"] = "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
  37. flag.StringVar(&passphrase, "diceware", "", "a diceware passphrase")
  38. flag.IntVar(&words, "words", 0, "How many words")
  39. flag.StringVar(&passphrase, "random", "", "a random string password")
  40. flag.StringVar(&passphrase, "insecure", "", "a human invented password")
  41. dicewareCommand := flag.NewFlagSet("diceware", flag.ExitOnError)
  42. passphraseFlag := dicewareCommand.String("passphrase", "", "the passphrase")
  43. wordsFlag := dicewareCommand.Int("words", 0, "number of words in passphrase")
  44. dictSizeFlag := dicewareCommand.Int("dictSize", 0, "number of words in dictionary")
  45. randomCommand := flag.NewFlagSet("random", flag.ExitOnError)
  46. insecureCommand := flag.NewFlagSet("insecure", flag.ExitOnError)
  47. insecureWords := insecureCommand.Int("words", 0, "number of words in invented passphrase")
  48. if len(os.Args) == 1 {
  49. myUsage()
  50. return
  51. }
  52. switch os.Args[1] {
  53. case "diceware":
  54. dicewareCommand.Parse(os.Args[2:])
  55. case "random":
  56. randomCommand.Parse(os.Args[2:])
  57. case "insecure":
  58. insecureCommand.Parse(os.Args[2:])
  59. default:
  60. myUsage()
  61. fmt.Printf("\n%q is not valid command.\n", os.Args[1])
  62. os.Exit(2)
  63. }
  64. if dicewareCommand.Parsed() {
  65. if *passphraseFlag == "" {
  66. dicewareCommand.Usage()
  67. return
  68. }
  69. if *wordsFlag == 0 {
  70. dicewareCommand.Usage()
  71. return
  72. }
  73. if *dictSizeFlag == 0 {
  74. dicewareCommand.Usage()
  75. return
  76. }
  77. entropy := math.Log2(math.Pow(float64(*dictSizeFlag), float64(*wordsFlag)))
  78. fmt.Println("\nPassphrase entropy:", entropy)
  79. }
  80. if randomCommand.Parsed() {
  81. passphraseLength := len(passphrase)
  82. for key, value := range charsets {
  83. if strings.ContainsAny(passphrase, value) {
  84. possibleSymbols += len(value)
  85. usedCharsets = append(usedCharsets, key)
  86. }
  87. }
  88. entropy := math.Log2(math.Pow(float64(possibleSymbols), float64(passphraseLength)))
  89. fmt.Println("\nNumber of characters:", passphraseLength)
  90. fmt.Println("\nUsed character sets:", strings.Join(usedCharsets, ", "))
  91. fmt.Println("\nPassphrase entropy:", entropy)
  92. }
  93. if insecureCommand.Parsed() {
  94. if *insecureWords != 0 {
  95. insecureCommand.Usage()
  96. return
  97. }
  98. }
  99. }