-
-
Save steverichey/6fb2f5e3684ca527497cd88bc8e720e7 to your computer and use it in GitHub Desktop.
Simple password generator, version 2
This file contains 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
#!/usr/bin/env sh | |
set -eur | |
generate() | |
{ | |
allowed_characters="${1}" | |
number_of_characters="${2}" | |
cat /dev/random | env LC_CTYPE=C tr -cd "${allowed_characters}" | head -c "${number_of_characters}" | |
} | |
get_line() | |
{ | |
line_number="${1}" | |
file_name="${2}" | |
awk '/'${line_number}'/{ print NR; exit }' "${file_name}" | |
} | |
get_word() | |
{ | |
text_line="${1}" | |
file_name="${2}" | |
awk 'NR=='${text_line}'' ${file_name} | |
} | |
echored() | |
{ | |
(>&2 echo "\033[1;31m${1}\033[0m") | |
} | |
echoyellow() | |
{ | |
echo "\033[1;33m${1}\033[0m" | |
} | |
echogreen() | |
{ | |
echo "\033[1;32m${1}\033[0m" | |
} | |
usage () | |
{ | |
echogreen "Usage: pw [options] length" | |
echo "Generates a random password with the given limitations, and copies to the clipboard" | |
echo "\t-n\tNumeric character limitation" | |
echo "\t-a\tAlphabetic character limitation" | |
echo "\t-l\tLowercase character limitation" | |
echo "\t-d\tDiceware passphrase (exclusive to other options)" | |
echo "\t-p\tPrint password or passphrase instead of copying to clipboard" | |
echo "" | |
exit 1 | |
} | |
numeric_characters=0 | |
alpha_characters=0 | |
lowercase_characters=0 | |
diceware=0 | |
print_output=0 | |
length="" | |
numeric_regex="^[0-9]+$" | |
# parse arguments | |
while [ $# -gt 0 ] | |
do | |
case "${1}" in | |
"-h"|"--help") | |
usage | |
shift | |
;; | |
"-n"|"--numeric") | |
numeric_characters=1 | |
shift | |
;; | |
"-a"|"--alpha") | |
alpha_characters=1 | |
shift | |
;; | |
"-l"|"--lowercase") | |
lowercase_characters=1 | |
shift | |
;; | |
"-d"|"--diceware"|"-w") | |
diceware=1 | |
shift | |
;; | |
"-p"|"--print") | |
print_output=1 | |
shift | |
;; | |
*) # all other parameters | |
if [[ "${length}" == "" && "${1}" =~ ${numeric_regex} ]]; then | |
length="${1}" | |
else | |
echored "Invalid or unexpected argument: ${1}" | |
exit 1 | |
fi | |
shift | |
;; | |
esac | |
done | |
if [ "${length}" == "" ]; then | |
echored "Length is required; must be a numeric value" | |
exit 1 | |
fi | |
numeric_regex="^[0-9]+$" | |
if ! [[ "${length}" =~ ${numeric_regex} ]] ; then | |
echored "Given value was not a number" | |
exit 1 | |
fi | |
if [ "${diceware}" == "1" ]; then | |
set +u | |
if [ -z "${DICEWARE_FILENAME}" ]; then | |
echored "Please set DICEWARE_FILENAME to the location of your diceware text file." | |
exit 1 | |
fi | |
phrase="" | |
for i in `seq 1 ${length}` | |
do | |
dice_number=`generate '1-6' 5` | |
word_line=`get_line "${dice_number}" "${DICEWARE_FILENAME}"` | |
whole_word=`get_word "${word_line}" "${DICEWARE_FILENAME}"` | |
split_word=(${whole_word// / }) | |
phrase="${phrase} ${split_word[1]}" | |
done | |
set -u | |
if [ "${print_output}" == "1" ]; then | |
echo ${phrase} | |
else | |
echo ${phrase} | tr -d '\n' | pbcopy | |
echogreen "Copied to clipboard" | |
fi | |
else | |
allowed_characters="" | |
if [ "${numeric_characters}" == "1" ]; then | |
allowed_characters="${allowed_characters}0-9" | |
fi | |
if [ "${alpha_characters}" == "1" ]; then | |
if [ "${lowercase_characters}" == "1" ]; then | |
allowed_characters="${allowed_characters}a-z" | |
else | |
allowed_characters="${allowed_characters}A-Za-z" | |
fi | |
fi | |
if [ "${allowed_characters}" == "" ]; then | |
allowed_characters='a-zA-Z0-9`~!@#$%^&*()_+-={}[]|;<,>.?/' | |
fi | |
if [ "${print_output}" == "1" ]; then | |
generate "${allowed_characters}" "${length}" | xargs echo | |
else | |
generate "${allowed_characters}" "${length}" | pbcopy | |
echogreen "Copied to clipboard" | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment