Created
February 13, 2026 14:06
-
-
Save dzogrim/4b0e9f571dd88ff4e702f75e655f6867 to your computer and use it in GitHub Desktop.
This tool provides controlled, portable, reproducible, dependency-free secure password generation for production environments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # passwordGeneration — portable POSIX version | |
| # Version: 2.0 | |
| # Why use this script instead of: | |
| # openssl rand -hex 32 | |
| # gpg --armor --gen-random 0 "$((100 * 3/4))" | cut -c -50 | |
| # | |
| # Advantages: | |
| # | |
| # 1. Character set control | |
| # - Not limited to hex (0-9a-f) | |
| # - Not limited to base64 (+ / =) | |
| # - Fully configurable printable charset | |
| # - Avoids visually ambiguous characters if desired | |
| # | |
| # 2. Exact length guarantee | |
| # - No padding trimming | |
| # - No base64 rounding artifacts | |
| # - No post-processing with cut | |
| # | |
| # 3. Dependency-free | |
| # - No OpenSSL requirement | |
| # - No GPG installation required | |
| # - Works in minimal containers and recovery shells | |
| # | |
| # 4. Portable | |
| # - POSIX-only | |
| # - Works on macOS (BSD userland) and Linux | |
| # - No GNU-specific assumptions | |
| # | |
| # 5. Predictable output | |
| # - One password per line | |
| # - Supports generating N passwords | |
| # - Clean stdout, no metadata noise | |
| # | |
| # 6. Security properties | |
| # - Uses /dev/urandom directly | |
| # - No modulo bias | |
| # - No PRNG fallback | |
| # - No shell $RANDOM | |
| # | |
| # 7. Scriptability | |
| # - Suitable for automation | |
| # - Stable CLI interface | |
| # - Easy to embed in CI/CD | |
| # | |
| # Summary: | |
| # This tool provides controlled, portable, reproducible, | |
| # dependency-free secure password generation for production | |
| # environments. | |
| # | |
| set -eu | |
| DEFAULT_LENGTH=20 | |
| DEFAULT_COUNT=1 | |
| usage() { | |
| echo "Usage:" | |
| echo " $0 [length]" | |
| echo " $0 -l length [-n count]" | |
| exit 2 | |
| } | |
| is_positive_int() { | |
| case "$1" in | |
| ''|*[!0-9]*) | |
| return 1 | |
| ;; | |
| *) | |
| [ "$1" -gt 0 ] 2>/dev/null | |
| ;; | |
| esac | |
| } | |
| generate_password() { | |
| length="$1" | |
| LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^&*()_+=-[]{}<>?,.' < /dev/urandom \ | |
| | head -c "$length" | |
| printf '\n' | |
| } | |
| length="$DEFAULT_LENGTH" | |
| count="$DEFAULT_COUNT" | |
| # --- argument parsing --- | |
| while [ $# -gt 0 ]; do | |
| case "$1" in | |
| -l) | |
| shift | |
| [ $# -gt 0 ] || usage | |
| is_positive_int "$1" || usage | |
| length="$1" | |
| ;; | |
| -n) | |
| shift | |
| [ $# -gt 0 ] || usage | |
| is_positive_int "$1" || usage | |
| count="$1" | |
| ;; | |
| -h) | |
| usage | |
| ;; | |
| -*) | |
| usage | |
| ;; | |
| *) | |
| # positional length | |
| is_positive_int "$1" || usage | |
| length="$1" | |
| ;; | |
| esac | |
| shift | |
| done | |
| # --- generation loop --- | |
| i=0 | |
| while [ "$i" -lt "$count" ]; do | |
| generate_password "$length" | |
| i=`expr "$i" + 1` | |
| done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment