Skip to content

Instantly share code, notes, and snippets.

@AlexAtkinson
Created January 28, 2026 04:17
Show Gist options
  • Select an option

  • Save AlexAtkinson/99e7eb85fdc95b36a1978e4e7e8e92ac to your computer and use it in GitHub Desktop.

Select an option

Save AlexAtkinson/99e7eb85fdc95b36a1978e4e7e8e92ac to your computer and use it in GitHub Desktop.
Password Generator v2
#!/usr/bin/env bash
# v1: https://gist.github.com/AlexAtkinson/7a60dc26a8dd94fb910e01529b379ae2
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# PW Material Generator
# Notes:
# - Used by genpass
# - Generates 20 characters per invocation
# - Takes ~1ms per character generated on an average
# system
# - Will _always_ lead with an ALPHA character
# - Will _always_ include _at least one SPECIAL character
# when the -s argument is supplied
# Arguments:
# - -s Include special characters
# Outputs:
# - Randomly generated password 20 characters in length
# TODO:
# - Allow SPEC input to facilitate various tool compliance
# Previously looped pwgen until a compliant string was
# produced.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__genpass_fount() {
local SPEC_SAFE ALPH_NUM ALPH_LEAD RANDUP OUTPUT_TAIL
[[ "$2" == "-s" ]] && loggerx ERROR "Length must be specified after any arguments." && return 1
if [[ "$1" == "-s" ]]; then
SPEC='!@#$%^&*()<>[]{}|_+-='
SPEC_SAFE="${SPEC:$(( RANDOM % ${#SPEC} )):1}"
ALPH_NUM=$(openssl rand -base64 128 | tr -dc 'a-zA-Z0-9' | tr -d '\n' | head -c 128)
ALPH_LEAD=$(openssl rand -base64 128 | tr -dc 'a-zA-Z' | tr -d '\n' | head -c 1)
RANDUP=$(echo -n "${SPEC}${ALPH_NUM}" | fold -w 1 | shuf | tr -d "\n" | head -c 18 | head -n 1)
OUTPUT_TAIL=$(echo -n "${RANDUP}${SPEC_SAFE}" | fold -w 1 | shuf | tr -d "\n")
echo "${ALPH_LEAD}${OUTPUT_TAIL}"
else
openssl rand -base64 128 | tr -dc 'a-zA-Z0-9' | head -c 20 | head -n 1
echo ''
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# PW Generator
# Notes:
# - Same as __genpass_fount
# - No length limitation
# - Defaults to 20 characters
# Arguments:
# - -s Include special characters
# - <len> int Length of the output string
# Outputs:
# - Randomly generated password of any length.
# Cyclomatic Complexity: 7
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
genpass() {
[[ "$2" == "-s" ]] && loggerx ERROR "Length must be specified after any arguments." && return 1
local LEN="20"
local FOUNT_LEN='20'
if [[ "$1" == "-s" ]]; then
{ [[ -n $2 ]] && [[ $2 -ne $FOUNT_LEN ]] ; } && local LEN="$2"
local GEN_RUNS=$(( (LEN / FOUNT_LEN) + 1 ))
for ((GEN=0; GEN <= GEN_RUNS; GEN++)); do
__genpass_fount -s | tr -d '\n'
done | head -c "$LEN"
echo ''
else
{ [[ -n $1 ]] && [[ $1 -ne $FOUNT_LEN ]] ;} && local LEN="$1"
local GEN_RUNS=$(( (LEN / FOUNT_LEN) + 1 ))
for ((GEN=0; GEN <= GEN_RUNS; GEN++)); do
__genpass_fount | tr -d '\n'
done | head -c "$LEN"
echo ''
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment