Skip to content

Commit ebff0b4

Browse files
authored
Update random_password.sh
1 parent e428783 commit ebff0b4

File tree

1 file changed

+140
-15
lines changed

1 file changed

+140
-15
lines changed

src/random_password.sh

+140-15
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,154 @@
11
#!/usr/bin/env bash
22

33
# Script Name: random_password.sh
4-
# Description: Script that generates a random password of the specified length.
5-
# Usage: random_password.sh [n]
6-
# [n] - the length of the requested password
7-
# Example: ./random_password.sh 15
8-
9-
main() {
10-
if [ $# -ne 1 ]; then
11-
echo "Usage: random_password.sh [n]"
12-
echo " [n] - the length of the requested password"
13-
echo "Example: ./random_password.sh 15"
4+
# Description: Generates a random password with various customization options.
5+
#
6+
# Usage: random_password.sh [options]
7+
#
8+
# Options:
9+
# -h, --help Display this help message and exit.
10+
# -l, --length N Specify the length of the password (default: 12).
11+
# -s, --special Include special characters in the password.
12+
# -n, --numbers Include numbers in the password.
13+
# -u, --uppercase Include uppercase letters in the password.
14+
# -e, --exclude CHARS Exclude specific characters from the password.
15+
# -c, --count N Generate N passwords (default: 1).
16+
# -r, --repeat-allowed Allow characters to be repeated (default: true).
17+
#
18+
# Examples:
19+
# ./random_password.sh --length 15 --special --numbers
20+
# ./random_password.sh -l 20 -snu -e 'oO0l1I' --count 5
21+
# ./random_password.sh --length 16 --no-repeat
22+
23+
set -euo pipefail
24+
25+
function show_help() {
26+
grep '^#' "$0" | cut -c 4-
27+
exit 0
28+
}
29+
30+
function generate_password() {
31+
local length="$1"
32+
local charset="$2"
33+
local repeat_allowed="$3"
34+
35+
if [ -z "$charset" ]; then
36+
echo "Error: Character set is empty. Cannot generate password."
1437
exit 1
1538
fi
1639

17-
re='^[0-9]+$'
18-
if ! [[ $1 =~ $re ]]; then
19-
echo "Error: $1 is not an integer"
40+
if [ "${#charset}" -lt "$length" ] && [ "$repeat_allowed" = false ]; then
41+
echo "Error: Not enough unique characters in character set to generate a password of length $length without repeating characters."
2042
exit 1
2143
fi
2244

23-
password=$(strings /dev/urandom | grep -o '[[:alnum:]]' | head -n "$1" | tr -d '\n')
45+
local password=""
46+
if [ "$repeat_allowed" = true ]; then
47+
password=$(LC_ALL=C tr -dc "$charset" </dev/urandom | head -c "$length")
48+
else
49+
password=$(LC_ALL=C echo "$charset" | fold -w1 | shuf | tr -d '\n' | head -c "$length")
50+
fi
51+
2452
echo "$password"
53+
}
54+
55+
function main() {
56+
# Default values
57+
LENGTH=12
58+
INCLUDE_SPECIAL=false
59+
INCLUDE_NUMBERS=false
60+
INCLUDE_UPPERCASE=false
61+
EXCLUDE_CHARS=""
62+
COUNT=1
63+
REPEAT_ALLOWED=true
2564

65+
# Parse options
66+
while [[ $# -gt 0 ]]; do
67+
case "$1" in
68+
-h|--help)
69+
show_help
70+
;;
71+
-l|--length)
72+
if [[ -n "${2:-}" && "$2" =~ ^[0-9]+$ && "$2" -gt 0 ]]; then
73+
LENGTH="$2"
74+
shift 2
75+
else
76+
echo "Error: --length option requires a positive integer argument."
77+
exit 1
78+
fi
79+
;;
80+
-s|--special)
81+
INCLUDE_SPECIAL=true
82+
shift
83+
;;
84+
-n|--numbers)
85+
INCLUDE_NUMBERS=true
86+
shift
87+
;;
88+
-u|--uppercase)
89+
INCLUDE_UPPERCASE=true
90+
shift
91+
;;
92+
-e|--exclude)
93+
if [[ -n "${2:-}" ]]; then
94+
EXCLUDE_CHARS="$2"
95+
shift 2
96+
else
97+
echo "Error: --exclude option requires an argument."
98+
exit 1
99+
fi
100+
;;
101+
-c|--count)
102+
if [[ -n "${2:-}" && "$2" =~ ^[0-9]+$ && "$2" -gt 0 ]]; then
103+
COUNT="$2"
104+
shift 2
105+
else
106+
echo "Error: --count option requires a positive integer argument."
107+
exit 1
108+
fi
109+
;;
110+
-r|--repeat-allowed)
111+
REPEAT_ALLOWED=true
112+
shift
113+
;;
114+
--no-repeat)
115+
REPEAT_ALLOWED=false
116+
shift
117+
;;
118+
-*)
119+
echo "Unknown option: $1"
120+
show_help
121+
;;
122+
*)
123+
echo "Unknown argument: $1"
124+
show_help
125+
;;
126+
esac
127+
done
128+
129+
# Build the character set
130+
local charset="abcdefghijklmnopqrstuvwxyz"
131+
if [ "$INCLUDE_UPPERCASE" = true ]; then
132+
charset+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
133+
fi
134+
if [ "$INCLUDE_NUMBERS" = true ]; then
135+
charset+="0123456789"
136+
fi
137+
if [ "$INCLUDE_SPECIAL" = true ]; then
138+
charset+="!\"#\$%&'()*+,-./:;<=>?@[\]^_\`{|}~"
139+
fi
140+
141+
# Remove excluded characters
142+
if [ -n "$EXCLUDE_CHARS" ]; then
143+
for (( i=0; i<${#EXCLUDE_CHARS}; i++ )); do
144+
charset="${charset//${EXCLUDE_CHARS:i:1}/}"
145+
done
146+
fi
147+
148+
# Generate passwords
149+
for (( i=0; i<COUNT; i++ )); do
150+
generate_password "$LENGTH" "$charset" "$REPEAT_ALLOWED"
151+
done
26152
}
27153

28154
main "$@"
29-

0 commit comments

Comments
 (0)