-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
cmd_password.go
105 lines (86 loc) · 2.48 KB
/
cmd_password.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
import (
"flag"
"fmt"
"math/rand"
)
// Structure for our options and state.
type passwordCommand struct {
// The length of the password to generate
length int
// Specials?
specials bool
// Digits?
digits bool
// Confusing characters?
collide bool
}
// Arguments adds per-command args to the object.
func (p *passwordCommand) Arguments(f *flag.FlagSet) {
f.IntVar(&p.length, "length", 15, "The length of the password to generate")
f.BoolVar(&p.specials, "specials", true, "Should we use special characters?")
f.BoolVar(&p.digits, "digits", true, "Should we use digits?")
f.BoolVar(&p.collide, "ambiguous", false, "Should we allow ambiguous characters (0O1lI8B5S2ZD)?")
}
// Info returns the name of this subcommand.
func (p *passwordCommand) Info() (string, string) {
return "make-password", `Generate a random password.
Details:
This command generates a simple random password, by default being 12
characters long. You can tweak the alphabet used via the command-line
flags if necessary.`
}
// Execute is invoked if the user specifies `make-password` as the subcommand.
func (p *passwordCommand) Execute(args []string) int {
// Alphabets we use for generation
//
// Notice that some items are removed as "ambiguous":
//
// 0O1lI8B5S2ZD
//
digits := "34679"
specials := "~=&+%^*/()[]{}/!@#$?|"
upper := "ACEFGHJKLMNPQRTUVWXY"
lower := "abcdefghijkmnopqrstuvwxyz"
// Reinstate the missing characters, if we need to.
if p.collide {
digits = "0123456789"
upper = "ABCDEFGHIJKLMNOPQRSTUVWXY"
lower = "abcdefghijklmnopqrstuvwxy"
}
all := upper + lower
// Extend our alphabet if we should
if p.digits {
all = all + digits
}
if p.specials {
all = all + specials
}
// Make a buffer and fill it with all characters
buf := make([]byte, p.length)
for i := 0; i < p.length; i++ {
buf[i] = all[rand.Intn(len(all))]
}
// Add a digit if we should.
//
// We might already have them present, because our `all`
// alphabet was used already. But this ensures we have at
// least one digit present.
if p.digits {
buf[0] = digits[rand.Intn(len(digits))]
}
// Add a special-character if we should.
//
// We might already have them present, because our `all`
// alphabet was used already. But this ensures we have at
// least one special-character present.
if p.specials {
buf[1] = specials[rand.Intn(len(specials))]
}
// Shuffle and output
rand.Shuffle(len(buf), func(i, j int) {
buf[i], buf[j] = buf[j], buf[i]
})
fmt.Printf("%s\n", buf)
return 0
}