Last active 1 month ago

Generate rand password

botanikanet revised this gist 1 month ago. Go to revision

No changes

botanikanet revised this gist 1 month ago. Go to revision

1 file changed, 82 insertions

rand_pass.sh(file created)

@@ -0,0 +1,82 @@
1 + #!/bin/bash
2 + set -euo pipefail
3 +
4 + # ── Defaults ─────────────────────────────────────────────────────────
5 + DEFAULT_LENGTH=16
6 + CHARSET="alnum" # alnum | ascii
7 +
8 + # ── Usage ────────────────────────────────────────────────────────────
9 + usage() {
10 + cat <<EOF
11 + Usage: $(basename "$0") [OPTIONS] [LENGTH]
12 +
13 + Generate a random password of the given length (default: ${DEFAULT_LENGTH}).
14 +
15 + Options:
16 + -h, --help Show this help
17 + -s, --special Include special characters (!@#\$%^&*_+-=)
18 + -c, --copy Copy password to clipboard (requires wl-copy)
19 +
20 + Examples:
21 + $(basename "$0") # 16-char alphanumeric password
22 + $(basename "$0") 32 # 32-char alphanumeric password
23 + $(basename "$0") -s 24 # 24-char password with special characters
24 + $(basename "$0") -sc 20 # 20-char with specials, copied to clipboard
25 + EOF
26 + exit 1
27 + }
28 +
29 + # ── Parse arguments ──────────────────────────────────────────────────
30 + FLAG_COPY=""
31 +
32 + while (( $# )); do
33 + case "$1" in
34 + -h|--help) usage ;;
35 + -s|--special) CHARSET="ascii"; shift ;;
36 + -c|--copy) FLAG_COPY=1; shift ;;
37 + -sc|-cs) CHARSET="ascii"; FLAG_COPY=1; shift ;;
38 + -*) echo "Unknown option: $1" >&2; usage ;;
39 + *) break ;;
40 + esac
41 + done
42 +
43 + LENGTH="${1:-$DEFAULT_LENGTH}"
44 +
45 + # ── Validate length ─────────────────────────────────────────────────
46 + if ! [[ "$LENGTH" =~ ^[0-9]+$ ]] || (( LENGTH <= 0 )); then
47 + echo "Error: length must be a positive integer, got '${LENGTH}'" >&2
48 + exit 1
49 + fi
50 +
51 + # ── Generate password ───────────────────────────────────────────────
52 + # tr character classes:
53 + # alnum -> [A-Za-z0-9]
54 + # ascii -> [A-Za-z0-9] + special characters
55 + generate_password() {
56 + local len="$1"
57 + local filter
58 +
59 + case "$CHARSET" in
60 + alnum) filter='A-Za-z0-9' ;;
61 + ascii) filter='A-Za-z0-9!@#$%^&*_+\-=' ;;
62 + esac
63 +
64 + # Read enough random bytes to guarantee the desired length after filtering.
65 + # tr may exit with SIGPIPE once head has enough bytes — that is expected.
66 + LC_ALL=C tr -dc "$filter" </dev/urandom | head -c "$len" || true
67 + }
68 +
69 + PASSWORD="$(generate_password "$LENGTH")"
70 +
71 + # ── Output ───────────────────────────────────────────────────────────
72 + echo "$PASSWORD"
73 +
74 + # ── Copy to clipboard ───────────────────────────────────────────────
75 + if [[ -n "$FLAG_COPY" ]]; then
76 + if command -v wl-copy &>/dev/null; then
77 + echo -n "$PASSWORD" | wl-copy
78 + echo "(copied to clipboard)" >&2
79 + else
80 + echo "Warning: wl-copy not found (install wl-clipboard)" >&2
81 + fi
82 + fi
Newer Older