From 4124fe0c96d95c9f0add7d976121a861ed5fc477 Mon Sep 17 00:00:00 2001 From: Dennis Eriksen Date: Fri, 1 Sep 2023 05:50:05 +0200 Subject: Split makepass out of idgatt This will now be a separate repo --- bin/bin/makepass | 1 - bin/bin/makepass.bash | 59 -------------- bin/bin/makepass.sh | 110 -------------------------- bin/bin/makepass.zsh | 212 -------------------------------------------------- makepass | 1 + makepass.bash | 59 ++++++++++++++ makepass.sh | 110 ++++++++++++++++++++++++++ makepass.zsh | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 382 insertions(+), 382 deletions(-) delete mode 120000 bin/bin/makepass delete mode 100755 bin/bin/makepass.bash delete mode 100755 bin/bin/makepass.sh delete mode 100755 bin/bin/makepass.zsh create mode 120000 makepass create mode 100755 makepass.bash create mode 100755 makepass.sh create mode 100755 makepass.zsh diff --git a/bin/bin/makepass b/bin/bin/makepass deleted file mode 120000 index a40a9ef..0000000 --- a/bin/bin/makepass +++ /dev/null @@ -1 +0,0 @@ -makepass.zsh \ No newline at end of file diff --git a/bin/bin/makepass.bash b/bin/bin/makepass.bash deleted file mode 100755 index 0ebc60b..0000000 --- a/bin/bin/makepass.bash +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash -# Filename: ~/bin/makepass -# Purpose: Creating random passwords. -# Authors: Dennis Eriksen -# Some parts have been shamelessly stolen from other places. -# These parts will normally have a comment saying where it's -# from. For instance, this header format is stolen from the -# GRML-team (grml.org). -# Bug-Reports: Email -# License: This file is licensed under the GPL v2. -################################################################################ -# This file takes randomness from /dev/urandom and turns it into random -# passwords. -################################################################################ - - -# Copyright (c) 2018 Dennis Eriksen • d@ennis.no - -# makepass-function -function makepass { - local l=$1 - local words - local first - local last - MAKEPASS_WORDLIST=${MAKEPASS_WORDLIST:-/usr/share/dict/words} - # if $l is not a number, then exit - [[ ! $l =~ ^[0-9]+$ ]] && [[ ! "$l" == "" ]] && echo "not a number" && return 1 - # if $1 is actually empty, set $l to random value for each output - echo "Normal passwords:" - for i in {1..10}; do - [ "$1" = "" ] && l=$(shuf -i 8-44 -n 1) - head -n10 /dev/urandom | tr -dc _A-Z-a-z-0-9 | cut -c-${1:-$l}; - done | column - echo "" - - echo "Passwords with special characters:" - for i in {1..6}; do - [ "$1" = "" ] && l=$(shuf -i 16-64 -n 1) - first=$(head -n10 /dev/urandom | tr -dc A-Za-z | cut -c-1) - words=$(head -n10 /dev/urandom | tr -dc '!#$%&/()=?+-_,.;:<>[]{}|\@*^A-Z-a-z-0-9' | cut -c-${1:-$l}) - last=$(head -n10 /dev/urandom | tr -dc A-Za-z | cut -c-1) - echo "${first}${words}${last}" - done | column - - if [ -r "${MAKEPASS_WORDLIST}" ]; then - echo "" - echo "Passphrases:" - - for i in {1..5}; do - words=$(shuf -n 8 "${MAKEPASS_WORDLIST}" | tr '\n' '-' | tr -dc '_A-Z-a-z-0-9') - echo "${words:0:-1}" - done; - fi -} - -makepass "${@:-}" - -## END OF FILE ################################################################# -# vim:syntax=sh filetype=sh diff --git a/bin/bin/makepass.sh b/bin/bin/makepass.sh deleted file mode 100755 index 7db96fd..0000000 --- a/bin/bin/makepass.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env sh -# Filename: ~/bin/makepass.sh -# Purpose: Creating random passwords. -# Authors: Dennis Eriksen -# Bug-Reports: Email -# License: This file is licensed under the GPL v2. -################################################################################ -# This file takes randomness from /dev/urandom and turns it into random -# passwords. -# -# This particualr script is meant to be fully POSIX compatible. -################################################################################ - - -# Copyright (c) 2018-2022 Dennis Eriksen • d@ennis.no - -# makepass-function -makepass() { - MAKEPASS_WORDLIST=${MAKEPASS_WORDLIST:-/usr/share/dict/words} - - # We only take one argument - [ "$#" -gt 1 ] && printf '%s\n' 'only one argument' && return 1 - - # if $1 is not empty and is not a number - if [ ! -z "$1" ] && ! printf '%d' "$1" >/dev/null 2>&1; then printf '%s\n' 'not a number' && return 1; fi - if [ ! -z "$1" ] && [ ! ${1:-0} -gt 0 ]; then printf '%s\n' 'not a number above 0'; return 1; fi - - # Go! - len=$1 - - printf '%s\n' 'Normal passwords:' - i=0 - while [ $i -lt 10 ]; do - _random "${len:-}" '_A-Z-a-z-0-9' true - i=$((i + 1)) - done | column - printf '\n' - - printf '%s\n' 'Passwords with special characters:' - i=0 - while [ $i -lt 6 ]; do - _random "${len:-}" '!#$%&/()=?+-_,.;:<>[]{}|\@*^A-Z-a-z-0-9' true - i=$((i + 1)) - done | column - - if [ -r "${MAKEPASS_WORDLIST}" ]; then - printf '\n' - printf '%s\n' 'Passphrases:' - lines=$(wc -l < ${MAKEPASS_WORDLIST}) - i=0 - while [ $i -lt 5 ]; do - # shuf is the best solution here, but it is very much not portable. - #words=$(shuf -n 8 "${MAKEPASS_WORDLIST}" | tr '\n' '-' | tr -dc '_A-Z-a-z-0-9') - words="" - j=0 - while [ $j -lt 8 ]; do - words="${words}-$(sed -n $(($(_RANDOM) % $lines + 1))p "${MAKEPASS_WORDLIST}" | tr -dc '_A-Z-a-z-0-9')" - j=$((j + 1)) - done - printf '%s\n' "${words#-}" - i=$((i + 1)) - done - fi - - unset len i lines j words - return 0 -} - -# get random number -_RANDOM() { - N=0 - while [ ! "$N" = "${N#0}" ]; do - N=$(head -n 100 /dev/urandom | tr -cd "[:digit:]" | tail -c 8) - done - printf '%s\n' "$N" && return 0 -} - -# Function to create random stuff -_random() ( - # sh does not like leading zeroes when doing math with numbers. Let's reset until we have a number that doesn't start with 0. - - # Default is a number between 8 and 44 - len=${1:-$(($(_RANDOM) % (44 - 8 + 1) + 8))} - - # Default to [:alnum:] if no chars are specified - chars=${2:-'[:alnum:]'} - - # First-Last-Alpha - if you want the first and the last letter to be from [:alpha:] - fla=${3:-'false'} - - if [ "$fla" = "true" ]; then - if [ $len -le 2 ]; then - string="$(head -n 10 /dev/urandom | tr -cd '[:alpha:]' | tail -c $len)" - else - string="$(head -n 10 /dev/urandom | tr -cd '[:alpha:]' | tail -c 1)" - string="${string}$(head -n 100 /dev/urandom | tr -cd "$chars" | tail -c $((len-2)))" - string="${string}$(head -n 10 /dev/urandom | tr -cd '[:alpha:]' | tail -c 1)" - fi - else - string="$(head -n 100 /dev/urandom | tr -cd "$chars" | tail -c $len)" - fi - - printf '%s\n' "$string" - unset len chars fla string - return 0 -) - -makepass "${@:-}" - -## END OF FILE ################################################################# diff --git a/bin/bin/makepass.zsh b/bin/bin/makepass.zsh deleted file mode 100755 index 319a200..0000000 --- a/bin/bin/makepass.zsh +++ /dev/null @@ -1,212 +0,0 @@ -#!/usr/bin/env zsh -emulate zsh -# Filename: ~/bin/makepass.zsh -# Purpose: Creating random passwords. -# Authors: Dennis Eriksen -# Bug-Reports: Email -# License: This file is licensed under the GPL v2. -################################################################################ -# This file takes randomness from /dev/urandom and turns it into random -# passwords. -################################################################################ -# Copyright (c) 2018-2022 Dennis Eriksen • d@ennis.no - - -# Help-function -function _makepass_help() { - local string='NAME - makepass - create several random passwords - -SYNOPSIS - makepass [OPTIONS] [NUM] - - If a NUM is provided, the we will output passwords of that length. - - By default `makepass` will output passwords from the three following classes: - - - Normal passwords - 10 random strings with letters (both lower and upper - case), numbers, and dashes and underscores. - - - Passwords with special characters - six random strings generated from - lower and upper case letters, numbers, and the following characters: - !#$%&/()=?+-_,.;:<>[]{}|\@* - - - Passphrases - if we find a dictionary, five series of eight random words - from the dictionary, separated by dashes. The number of words can not be - changed, but you do not have to use all of them. Use as mane as you want. - -DESCRIPTION - makepass has the following options: - - -h - output this help-text - -ENVIRONMENT - makepass examines the following environmental variables. - - MAKEPASS_DEFAULT_LENGTH - Specifies the default length of passwords. Valid values are "random" - (default), or a number. If "random", a random value between 8 and 42 - will be used for each password. If `makepass` is run with a NUM as an - argument, that NUM overrides this variable. - - MAKEPASS_NORMAL - String of characters from which to generate "normal" passwords. - Defaults to: - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_ - - MAKEPASS_SPECIAL - String of characters from which to generate passwords with special - characters. Defaults to the same characters as in MAKEPASS_NORMAL, plus - these: - !#$%&/()=?+-_,.;:<>[]{}|\@* - - MAKEPASS_WORDLIST - Specifies the dictionary we find words for passphrases in. If this is - unset or empty, we try "/usr/share/dict/words". If that file does not - exist, no passphrases will be provided. - -NOTES - This scripts makes use of $RANDOM - a builtin in zsh which produces a - pseudo-random integer between 0 and 32767, newly generated each time the - parameter is referenced. We initially seed the random number generator with - a random 32bit integer generated from /dev/urandom. This should provide - enough randomnes to generate sufficiently secure passwords. - -AUTHOR - Dennis Eriksen ' - - print -- $string - return 0 -} - - - -# Create random passphrase -function randphrase() { - setopt localoptions rematch_pcre - local -i len=${1:-8} - local prestring string - - # Put together $len random words, separated by '-' - repeat $len prestring+=$words[$((RANDOM % $#words + 1))]'-' - prestring=$prestring[1,-2] # remove trailing dash - - # This while-loop removes any characters NOT in '[^0-9a-zA-Z_-]' - while [[ -n $prestring ]]; do - if [[ $prestring =~ '[^0-9a-zA-Z_-]' ]]; then - string+=${prestring[1,MBEGIN-1]} - prestring=${prestring[MEND+1,-1]} - else - break - fi - done - string+=$prestring # append the rest of $prestring - - printf '%s\n' $string; return -} - - - -# Function to create random strings -function randstring() { - # Default is a number between 8 and 44 - local -i len=$(( ${1:-0} > 0 ? ${1:-0} : RANDOM % (44 - 8 + 1) + 8)) - local chars=${2:-$alnum} - local flc=${3:-} # first-last-character - local string - repeat $len string+=$chars[$((RANDOM % $#chars + 1))] - - # If a third value is provided, it is used as the forst and last character in - # the string - if [[ -n $flc ]]; then - string=$flc[$((RANDOM % $#flc + 1))]$string[2,-2] - (( len >= 2 )) && string+=$flc[$((RANDOM % $#flc + 1))] - fi - - printf '%s\n' "$string"; return -} - - - -# makepass-function. This is where the magic happens -function makepass() { - setopt localoptions - local lower='abcdefghijklmnopqrstuvwxyz' - local upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ' - local digit='0123456789' - local other='!#$%&/()=?+-_,.;:<>[]{}|\@*' - local alpha=${lower}${upper} - local alnum=${alpha}${digit} - local every=${alnum}${other} - - local length=${MAKEPASS_DEFAULT_LENGTH:-random} - local normal=${MAKEPASS_NORMAL:-$alnum'-_'} - local special=${MAKEPASS_SPECIAL:-$every} - local wordlist=${MAKEPASS_WORDLIST:-/usr/share/dict/words} - - # Seed $RANDOM with a random 32bit integer from /dev/urandom - local r4 # will be filled with 4 random bytes from /dev/urandom - IFS= read -rk4 -u0 r4 < /dev/urandom || return - local b1=$r4[1] b2=$r4[2] b3=$r4[3] b4=$r4[4] - RANDOM=$(( #b1 << 24 | #b2 << 16 | #b3 << 8 | #b4 )) - - - # Some error-checking - # We only take one argument - (( ARGC > 1 )) && print -u2 -- "only one argument\nmaybe try running \`makepass -h\` for help" && return 1 - # if $1 == -h - [[ $1 == '-h' ]] && _makepass_help && return 0 - # if $1 is not empty and is not a number - [[ -n $1 && ! $1 = <1-> ]] && print -u2 -- "not a number above 0\nmaybe try running \`makepass -h\` for help" && return 1 - - # length of passwords - local -i len=$(( length > 0 && ! ${1:-0} > 0 ? length : ${1:-0} )) - - # Normal passwords - print "Normal passwords:" - print -c -- $(repeat 10 { randstring $len $normal; : $RANDOM }) - : $RANDOM - print - - # Passowrds with special characters - print "Passwords with special characters:" - print -c -- $(repeat 6 { randstring $len $special $alpha; : $RANDOM }) - : $RANDOM - - # Passphrases - but only if a wordlist is available - if [[ -r $wordlist ]]; then - print - print "Passphrases:" - local -a words=(${(f)"$(<"$wordlist")"}) - repeat 6 randphrase - fi -} - -makepass "${@:-}" - -# Last time I redid this script I benchmarked some ways to generate random -# strings. Here's the results: - -# subshell with tr | fold | head -# % time (repeat 10000 { string=''; string=$(tr -cd '[:alpha:]' +# Some parts have been shamelessly stolen from other places. +# These parts will normally have a comment saying where it's +# from. For instance, this header format is stolen from the +# GRML-team (grml.org). +# Bug-Reports: Email +# License: This file is licensed under the GPL v2. +################################################################################ +# This file takes randomness from /dev/urandom and turns it into random +# passwords. +################################################################################ + + +# Copyright (c) 2018 Dennis Eriksen • d@ennis.no + +# makepass-function +function makepass { + local l=$1 + local words + local first + local last + MAKEPASS_WORDLIST=${MAKEPASS_WORDLIST:-/usr/share/dict/words} + # if $l is not a number, then exit + [[ ! $l =~ ^[0-9]+$ ]] && [[ ! "$l" == "" ]] && echo "not a number" && return 1 + # if $1 is actually empty, set $l to random value for each output + echo "Normal passwords:" + for i in {1..10}; do + [ "$1" = "" ] && l=$(shuf -i 8-44 -n 1) + head -n10 /dev/urandom | tr -dc _A-Z-a-z-0-9 | cut -c-${1:-$l}; + done | column + echo "" + + echo "Passwords with special characters:" + for i in {1..6}; do + [ "$1" = "" ] && l=$(shuf -i 16-64 -n 1) + first=$(head -n10 /dev/urandom | tr -dc A-Za-z | cut -c-1) + words=$(head -n10 /dev/urandom | tr -dc '!#$%&/()=?+-_,.;:<>[]{}|\@*^A-Z-a-z-0-9' | cut -c-${1:-$l}) + last=$(head -n10 /dev/urandom | tr -dc A-Za-z | cut -c-1) + echo "${first}${words}${last}" + done | column + + if [ -r "${MAKEPASS_WORDLIST}" ]; then + echo "" + echo "Passphrases:" + + for i in {1..5}; do + words=$(shuf -n 8 "${MAKEPASS_WORDLIST}" | tr '\n' '-' | tr -dc '_A-Z-a-z-0-9') + echo "${words:0:-1}" + done; + fi +} + +makepass "${@:-}" + +## END OF FILE ################################################################# +# vim:syntax=sh filetype=sh diff --git a/makepass.sh b/makepass.sh new file mode 100755 index 0000000..7db96fd --- /dev/null +++ b/makepass.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env sh +# Filename: ~/bin/makepass.sh +# Purpose: Creating random passwords. +# Authors: Dennis Eriksen +# Bug-Reports: Email +# License: This file is licensed under the GPL v2. +################################################################################ +# This file takes randomness from /dev/urandom and turns it into random +# passwords. +# +# This particualr script is meant to be fully POSIX compatible. +################################################################################ + + +# Copyright (c) 2018-2022 Dennis Eriksen • d@ennis.no + +# makepass-function +makepass() { + MAKEPASS_WORDLIST=${MAKEPASS_WORDLIST:-/usr/share/dict/words} + + # We only take one argument + [ "$#" -gt 1 ] && printf '%s\n' 'only one argument' && return 1 + + # if $1 is not empty and is not a number + if [ ! -z "$1" ] && ! printf '%d' "$1" >/dev/null 2>&1; then printf '%s\n' 'not a number' && return 1; fi + if [ ! -z "$1" ] && [ ! ${1:-0} -gt 0 ]; then printf '%s\n' 'not a number above 0'; return 1; fi + + # Go! + len=$1 + + printf '%s\n' 'Normal passwords:' + i=0 + while [ $i -lt 10 ]; do + _random "${len:-}" '_A-Z-a-z-0-9' true + i=$((i + 1)) + done | column + printf '\n' + + printf '%s\n' 'Passwords with special characters:' + i=0 + while [ $i -lt 6 ]; do + _random "${len:-}" '!#$%&/()=?+-_,.;:<>[]{}|\@*^A-Z-a-z-0-9' true + i=$((i + 1)) + done | column + + if [ -r "${MAKEPASS_WORDLIST}" ]; then + printf '\n' + printf '%s\n' 'Passphrases:' + lines=$(wc -l < ${MAKEPASS_WORDLIST}) + i=0 + while [ $i -lt 5 ]; do + # shuf is the best solution here, but it is very much not portable. + #words=$(shuf -n 8 "${MAKEPASS_WORDLIST}" | tr '\n' '-' | tr -dc '_A-Z-a-z-0-9') + words="" + j=0 + while [ $j -lt 8 ]; do + words="${words}-$(sed -n $(($(_RANDOM) % $lines + 1))p "${MAKEPASS_WORDLIST}" | tr -dc '_A-Z-a-z-0-9')" + j=$((j + 1)) + done + printf '%s\n' "${words#-}" + i=$((i + 1)) + done + fi + + unset len i lines j words + return 0 +} + +# get random number +_RANDOM() { + N=0 + while [ ! "$N" = "${N#0}" ]; do + N=$(head -n 100 /dev/urandom | tr -cd "[:digit:]" | tail -c 8) + done + printf '%s\n' "$N" && return 0 +} + +# Function to create random stuff +_random() ( + # sh does not like leading zeroes when doing math with numbers. Let's reset until we have a number that doesn't start with 0. + + # Default is a number between 8 and 44 + len=${1:-$(($(_RANDOM) % (44 - 8 + 1) + 8))} + + # Default to [:alnum:] if no chars are specified + chars=${2:-'[:alnum:]'} + + # First-Last-Alpha - if you want the first and the last letter to be from [:alpha:] + fla=${3:-'false'} + + if [ "$fla" = "true" ]; then + if [ $len -le 2 ]; then + string="$(head -n 10 /dev/urandom | tr -cd '[:alpha:]' | tail -c $len)" + else + string="$(head -n 10 /dev/urandom | tr -cd '[:alpha:]' | tail -c 1)" + string="${string}$(head -n 100 /dev/urandom | tr -cd "$chars" | tail -c $((len-2)))" + string="${string}$(head -n 10 /dev/urandom | tr -cd '[:alpha:]' | tail -c 1)" + fi + else + string="$(head -n 100 /dev/urandom | tr -cd "$chars" | tail -c $len)" + fi + + printf '%s\n' "$string" + unset len chars fla string + return 0 +) + +makepass "${@:-}" + +## END OF FILE ################################################################# diff --git a/makepass.zsh b/makepass.zsh new file mode 100755 index 0000000..319a200 --- /dev/null +++ b/makepass.zsh @@ -0,0 +1,212 @@ +#!/usr/bin/env zsh +emulate zsh +# Filename: ~/bin/makepass.zsh +# Purpose: Creating random passwords. +# Authors: Dennis Eriksen +# Bug-Reports: Email +# License: This file is licensed under the GPL v2. +################################################################################ +# This file takes randomness from /dev/urandom and turns it into random +# passwords. +################################################################################ +# Copyright (c) 2018-2022 Dennis Eriksen • d@ennis.no + + +# Help-function +function _makepass_help() { + local string='NAME + makepass - create several random passwords + +SYNOPSIS + makepass [OPTIONS] [NUM] + + If a NUM is provided, the we will output passwords of that length. + + By default `makepass` will output passwords from the three following classes: + + - Normal passwords - 10 random strings with letters (both lower and upper + case), numbers, and dashes and underscores. + + - Passwords with special characters - six random strings generated from + lower and upper case letters, numbers, and the following characters: + !#$%&/()=?+-_,.;:<>[]{}|\@* + + - Passphrases - if we find a dictionary, five series of eight random words + from the dictionary, separated by dashes. The number of words can not be + changed, but you do not have to use all of them. Use as mane as you want. + +DESCRIPTION + makepass has the following options: + + -h + output this help-text + +ENVIRONMENT + makepass examines the following environmental variables. + + MAKEPASS_DEFAULT_LENGTH + Specifies the default length of passwords. Valid values are "random" + (default), or a number. If "random", a random value between 8 and 42 + will be used for each password. If `makepass` is run with a NUM as an + argument, that NUM overrides this variable. + + MAKEPASS_NORMAL + String of characters from which to generate "normal" passwords. + Defaults to: + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_ + + MAKEPASS_SPECIAL + String of characters from which to generate passwords with special + characters. Defaults to the same characters as in MAKEPASS_NORMAL, plus + these: + !#$%&/()=?+-_,.;:<>[]{}|\@* + + MAKEPASS_WORDLIST + Specifies the dictionary we find words for passphrases in. If this is + unset or empty, we try "/usr/share/dict/words". If that file does not + exist, no passphrases will be provided. + +NOTES + This scripts makes use of $RANDOM - a builtin in zsh which produces a + pseudo-random integer between 0 and 32767, newly generated each time the + parameter is referenced. We initially seed the random number generator with + a random 32bit integer generated from /dev/urandom. This should provide + enough randomnes to generate sufficiently secure passwords. + +AUTHOR + Dennis Eriksen ' + + print -- $string + return 0 +} + + + +# Create random passphrase +function randphrase() { + setopt localoptions rematch_pcre + local -i len=${1:-8} + local prestring string + + # Put together $len random words, separated by '-' + repeat $len prestring+=$words[$((RANDOM % $#words + 1))]'-' + prestring=$prestring[1,-2] # remove trailing dash + + # This while-loop removes any characters NOT in '[^0-9a-zA-Z_-]' + while [[ -n $prestring ]]; do + if [[ $prestring =~ '[^0-9a-zA-Z_-]' ]]; then + string+=${prestring[1,MBEGIN-1]} + prestring=${prestring[MEND+1,-1]} + else + break + fi + done + string+=$prestring # append the rest of $prestring + + printf '%s\n' $string; return +} + + + +# Function to create random strings +function randstring() { + # Default is a number between 8 and 44 + local -i len=$(( ${1:-0} > 0 ? ${1:-0} : RANDOM % (44 - 8 + 1) + 8)) + local chars=${2:-$alnum} + local flc=${3:-} # first-last-character + local string + repeat $len string+=$chars[$((RANDOM % $#chars + 1))] + + # If a third value is provided, it is used as the forst and last character in + # the string + if [[ -n $flc ]]; then + string=$flc[$((RANDOM % $#flc + 1))]$string[2,-2] + (( len >= 2 )) && string+=$flc[$((RANDOM % $#flc + 1))] + fi + + printf '%s\n' "$string"; return +} + + + +# makepass-function. This is where the magic happens +function makepass() { + setopt localoptions + local lower='abcdefghijklmnopqrstuvwxyz' + local upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ' + local digit='0123456789' + local other='!#$%&/()=?+-_,.;:<>[]{}|\@*' + local alpha=${lower}${upper} + local alnum=${alpha}${digit} + local every=${alnum}${other} + + local length=${MAKEPASS_DEFAULT_LENGTH:-random} + local normal=${MAKEPASS_NORMAL:-$alnum'-_'} + local special=${MAKEPASS_SPECIAL:-$every} + local wordlist=${MAKEPASS_WORDLIST:-/usr/share/dict/words} + + # Seed $RANDOM with a random 32bit integer from /dev/urandom + local r4 # will be filled with 4 random bytes from /dev/urandom + IFS= read -rk4 -u0 r4 < /dev/urandom || return + local b1=$r4[1] b2=$r4[2] b3=$r4[3] b4=$r4[4] + RANDOM=$(( #b1 << 24 | #b2 << 16 | #b3 << 8 | #b4 )) + + + # Some error-checking + # We only take one argument + (( ARGC > 1 )) && print -u2 -- "only one argument\nmaybe try running \`makepass -h\` for help" && return 1 + # if $1 == -h + [[ $1 == '-h' ]] && _makepass_help && return 0 + # if $1 is not empty and is not a number + [[ -n $1 && ! $1 = <1-> ]] && print -u2 -- "not a number above 0\nmaybe try running \`makepass -h\` for help" && return 1 + + # length of passwords + local -i len=$(( length > 0 && ! ${1:-0} > 0 ? length : ${1:-0} )) + + # Normal passwords + print "Normal passwords:" + print -c -- $(repeat 10 { randstring $len $normal; : $RANDOM }) + : $RANDOM + print + + # Passowrds with special characters + print "Passwords with special characters:" + print -c -- $(repeat 6 { randstring $len $special $alpha; : $RANDOM }) + : $RANDOM + + # Passphrases - but only if a wordlist is available + if [[ -r $wordlist ]]; then + print + print "Passphrases:" + local -a words=(${(f)"$(<"$wordlist")"}) + repeat 6 randphrase + fi +} + +makepass "${@:-}" + +# Last time I redid this script I benchmarked some ways to generate random +# strings. Here's the results: + +# subshell with tr | fold | head +# % time (repeat 10000 { string=''; string=$(tr -cd '[:alpha:]'