-
Notifications
You must be signed in to change notification settings - Fork 0
/
pwgen-word
executable file
·83 lines (64 loc) · 1.82 KB
/
pwgen-word
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
#!/bin/bash
set -eu
set -o pipefail
default_opts="-sy"
usage() {
cat >&2 <<EOM
usage: $(basename "$0") [-v] LENGTH [PWGEN_OPTS...]
Generate random passwords using pwgen that have no punctuation characters that
gnome-terminal considers to be word separators.
It sends pwgen a length that is 25% larger than LENGTH to get enough data.
If PWGEN_OPTS are given, they will be passed to pwgen. Otherwise, default
options of "$default_opts" will be used.
Punctuation according to gnome-terminal:
word separators: !"$'()*;<>[\\]^\`{|}
non separators: #%&+,-./:=?@_~
Caveat: The word separators have recently changed quite a bit.
https://askubuntu.com/a/725109/8807
https://bugs.launchpad.net/ubuntu/+source/gnome-terminal/+bug/1401207
There are 14 non-separators, so with default options there are 76 possible
symbols. Generated passwords will have somewhat less than 6.248 bits of entropy
per character because each one of symbols, uppercase, lowercase, and numbers
are required to be present by default.
OPTIONS
-v Be more verbose.
SEE ALSO
pwgen(1)
EOM
exit 1
}
log() {
test -n "$verbose" || return 0
echo >&2 "$*"
}
verbose=
if [ $# -ge 1 ] && [ "$1" = "-v" ]; then
verbose=1
shift
fi
if [ $# -lt 1 ]; then
usage
fi
target="$(printf "%d" "$1")"
shift
pwlen="$((target * 5 / 4))"
pwopts="$*"
if [ -z "$pwopts" ]; then
pwopts="$default_opts"
fi
while true; do
log "+ pwgen $pwopts $pwlen | tr -d "'!"$'\''()*;<>[\\]^`{|}'
pass="$(pwgen $pwopts "$pwlen" | tr -d '!"$'\''()*;<>[\\]^`{|}')"
len="${#pass}"
if [ "$len" -gt "$target" ]; then
log "len: $target (truncated from $len)"
pass="${pass:0:$target}"
break
elif [ "$len" -eq "$target" ]; then
log "len: $len"
break
else
log "len: $len"
fi
done
echo "$pass"