-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathrandom_password.sh
executable file
·154 lines (140 loc) · 4.42 KB
/
random_password.sh
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env bash
# Script Name: random_password.sh
# Description: Generates a random password with various customization options.
#
# Usage: random_password.sh [options]
#
# Options:
# -h, --help Display this help message and exit.
# -l, --length N Specify the length of the password (default: 12).
# -s, --special Include special characters in the password.
# -n, --numbers Include numbers in the password.
# -u, --uppercase Include uppercase letters in the password.
# -e, --exclude CHARS Exclude specific characters from the password.
# -c, --count N Generate N passwords (default: 1).
# -r, --repeat-allowed Allow characters to be repeated (default: true).
#
# Examples:
# ./random_password.sh --length 15 --special --numbers
# ./random_password.sh -l 20 -snu -e 'oO0l1I' --count 5
# ./random_password.sh --length 16 --no-repeat
set -euo pipefail
function show_help() {
grep '^#' "$0" | cut -c 4-
exit 0
}
function generate_password() {
local length="$1"
local charset="$2"
local repeat_allowed="$3"
if [ -z "$charset" ]; then
echo "Error: Character set is empty. Cannot generate password."
exit 1
fi
if [ "${#charset}" -lt "$length" ] && [ "$repeat_allowed" = false ]; then
echo "Error: Not enough unique characters in character set to generate a password of length $length without repeating characters."
exit 1
fi
local password=""
if [ "$repeat_allowed" = true ]; then
password=$(LC_ALL=C tr -dc "$charset" </dev/urandom | head -c "$length")
else
password=$(LC_ALL=C echo "$charset" | fold -w1 | shuf | tr -d '\n' | head -c "$length")
fi
echo "$password"
}
function main() {
# Default values
LENGTH=12
INCLUDE_SPECIAL=false
INCLUDE_NUMBERS=false
INCLUDE_UPPERCASE=false
EXCLUDE_CHARS=""
COUNT=1
REPEAT_ALLOWED=true
# Parse options
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
show_help
;;
-l|--length)
if [[ -n "${2:-}" && "$2" =~ ^[0-9]+$ && "$2" -gt 0 ]]; then
LENGTH="$2"
shift 2
else
echo "Error: --length option requires a positive integer argument."
exit 1
fi
;;
-s|--special)
INCLUDE_SPECIAL=true
shift
;;
-n|--numbers)
INCLUDE_NUMBERS=true
shift
;;
-u|--uppercase)
INCLUDE_UPPERCASE=true
shift
;;
-e|--exclude)
if [[ -n "${2:-}" ]]; then
EXCLUDE_CHARS="$2"
shift 2
else
echo "Error: --exclude option requires an argument."
exit 1
fi
;;
-c|--count)
if [[ -n "${2:-}" && "$2" =~ ^[0-9]+$ && "$2" -gt 0 ]]; then
COUNT="$2"
shift 2
else
echo "Error: --count option requires a positive integer argument."
exit 1
fi
;;
-r|--repeat-allowed)
REPEAT_ALLOWED=true
shift
;;
--no-repeat)
REPEAT_ALLOWED=false
shift
;;
-*)
echo "Unknown option: $1"
show_help
;;
*)
echo "Unknown argument: $1"
show_help
;;
esac
done
# Build the character set
local charset="abcdefghijklmnopqrstuvwxyz"
if [ "$INCLUDE_UPPERCASE" = true ]; then
charset+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
fi
if [ "$INCLUDE_NUMBERS" = true ]; then
charset+="0123456789"
fi
if [ "$INCLUDE_SPECIAL" = true ]; then
charset+="!\"#\$%&'()*+,-./:;<=>?@[\]^_\`{|}~"
fi
# Remove excluded characters
if [ -n "$EXCLUDE_CHARS" ]; then
for (( i=0; i<${#EXCLUDE_CHARS}; i++ )); do
charset="${charset//${EXCLUDE_CHARS:i:1}/}"
done
fi
# Generate passwords
for (( i=0; i<COUNT; i++ )); do
generate_password "$LENGTH" "$charset" "$REPEAT_ALLOWED"
done
}
main "$@"