#!/bin/bash -
# ------------------------------------------------------------------------------
# passwd-gen.sh
# =============
#
# Scope Native
# Copyright (C) 2024 by RaySoft, Zurich, Switzerland
# License GNU General Public License (GPL) 2.0
# https://www.gnu.org/licenses/gpl2.txt
#
# ------------------------------------------------------------------------------
set -o 'noglob' -o 'nounset' -o 'pipefail' # -o 'xtrace' -o 'errexit'
# ------------------------------------------------------------------------------
LENGTH=25
AMOUNT=10
UPPER='A-Z'
LOWER='a-z'
NUMBER='0-9'
SPECIAL='_,.!?&%=/*+-'
# ------------------------------------------------------------------------------
BC=('/usr/bin/bc' '-l')
CUT=('/usr/local/bin/gcut')
OPENSSL=('/usr/local/bin/openssl')
TR=('/usr/local/bin/gtr' '-cd')
WC=('/usr/local/bin/gwc' '-c')
# ------------------------------------------------------------------------------
if [[ ${LENGTH} -lt 6 ]]; then
echo "$0(${LINENO}): Password LENGTH must be at least 6 characters long."
exit 1
fi
if [[ ${AMOUNT} -lt 1 ]]; then
echo "$0(${LINENO}): Password AMOUNT must be at least 1."
exit 1
fi
# ------------------------------------------------------------------------------
count=0
pool=$(( 10 * LENGTH ))
min=( $("${BC[@]}" <<<"
define int(x) {
s = scale; scale = 0; x /= 1; scale = s; return x
}
define round(x) {
if (x < 0) x -= 0.5 else x += 0.5; return int(x)
}
round(${LENGTH} / 4); round(${length} / 8)
") )
while [[ ${count} -lt ${AMOUNT} ]]; do
passwd=$( \
"${OPENSSL[@]}" rand ${pool} \
| "${TR[@]}" "${UPPER}${LOWER}${NUMBER}${SPECIAL}" \
| "${CUT[@]}" -c "1-${LENGTH}" \
)
if [[ ${passwd:0:1} =~ [${UPPER}${LOWER}] \
&& ${passwd: -1} =~ [${UPPER}${LOWER}] ]]; then
if [[ $("${TR[@]}" "${SPECIAL}" <<<"${passwd}" | "${WC[@]}") -ge ${min[1]} \
&& $("${TR[@]}" "${NUMBER}" <<<"${passwd}" | "${WC[@]}") -ge ${min[1]} \
&& $("${TR[@]}" "${LOWER}" <<<"${passwd}" | "${WC[@]}") -ge ${min[0]} \
&& $("${TR[@]}" "${UPPER}" <<<"${passwd}" | "${WC[@]}") -ge ${min[0]} ]]; then
echo "${passwd}"
((count+=1))
fi
fi
done
# ------------------------------------------------------------------------------
exit 0