Update stow/bash/.bash_aliases
This commit is contained in:
@@ -36,3 +36,156 @@ alias test_git_1p='echo "Testing Git 1Password credential helper for github.com:
|
||||
alias op_signin='op signin'
|
||||
alias op_list='op item list --format=json | jq -r ".[] | \"\(.title) - \(.id)\""'
|
||||
alias op_debug_item='function _op_debug() { op item get "$1" --format=json | jq -r ".fields[] | \"\(.label // .id): \(.value // \"empty\")\""; }; _op_debug'
|
||||
|
||||
|
||||
|
||||
# Password generator: passgen
|
||||
# Usage examples:
|
||||
# passgen # 24 chars, a-zA-Z0-9, 1 password
|
||||
# passgen -l 40 -c 5 # 5 passwords, length 40
|
||||
# passgen --symbols # include safe symbols for .env
|
||||
# passgen --no-upper # remove uppercase
|
||||
# passgen --exclude '$"' # exclude specific chars
|
||||
# passgen --ambiguous # remove ambiguous chars (O0Il1)
|
||||
# passgen --strict # enforce "at least one of each selected class"
|
||||
|
||||
passgen() {
|
||||
local length=24 count=1
|
||||
local use_upper=1 use_lower=1 use_digits=1 use_symbols=0
|
||||
local strict=0 ambiguous=0
|
||||
local exclude=""
|
||||
local safe_symbols="!@#%^&*()_+.-" # .env-friendly (no quotes, $, `, \, =, :, space)
|
||||
local symbol_set="$safe_symbols" # can be extended later if you want a "wide" set
|
||||
|
||||
# parse args
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-l|--length) length="${2:-}"; shift 2 ;;
|
||||
-c|--count) count="${2:-}"; shift 2 ;;
|
||||
--no-upper) use_upper=0; shift ;;
|
||||
--no-lower) use_lower=0; shift ;;
|
||||
--no-digits) use_digits=0; shift ;;
|
||||
--symbols) use_symbols=1; shift ;;
|
||||
--no-symbols) use_symbols=0; shift ;;
|
||||
--exclude) exclude="${2:-}"; shift 2 ;;
|
||||
--ambiguous) ambiguous=1; shift ;;
|
||||
--strict) strict=1; shift ;;
|
||||
-h|--help)
|
||||
cat <<'EOF'
|
||||
passgen - flexible password generator
|
||||
|
||||
Options:
|
||||
-l, --length N Length of each password (default 24)
|
||||
-c, --count N How many passwords to generate (default 1)
|
||||
--no-upper Exclude A-Z
|
||||
--no-lower Exclude a-z
|
||||
--no-digits Exclude 0-9
|
||||
--symbols Include .env-safe symbols (!@#%^&*()_+.-)
|
||||
--no-symbols Exclude symbols (default)
|
||||
--exclude "xyz" Remove these characters from output
|
||||
--ambiguous Remove ambiguous characters: O 0 I l 1
|
||||
--strict Ensure each selected class appears at least once
|
||||
-h, --help Show this help
|
||||
|
||||
Notes:
|
||||
- Default charset: a-z A-Z 0-9
|
||||
- Symbols are .env-safe by default (no quotes, $, `, \, =, :, space)
|
||||
EOF
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo "passgen: unknown option: $1" >&2; return 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# sanity checks
|
||||
[[ "$length" =~ ^[0-9]+$ ]] || { echo "passgen: length must be a number" >&2; return 2; }
|
||||
[[ "$count" =~ ^[0-9]+$ ]] || { echo "passgen: count must be a number" >&2; return 2; }
|
||||
|
||||
# build class strings explicitly (no tr bracket weirdness)
|
||||
local UPPER="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
local LOWER="abcdefghijklmnopqrstuvwxyz"
|
||||
local DIGIT="0123456789"
|
||||
local SYMS="$symbol_set"
|
||||
|
||||
# optionally remove ambiguous chars
|
||||
if (( ambiguous )); then
|
||||
UPPER=${UPPER//O/}
|
||||
UPPER=${UPPER//I/}
|
||||
LOWER=${LOWER//l/}
|
||||
DIGIT=${DIGIT//0/}
|
||||
DIGIT=${DIGIT//1/}
|
||||
fi
|
||||
|
||||
# compose allowed set
|
||||
local allowed=""
|
||||
(( use_upper )) && allowed+="$UPPER"
|
||||
(( use_lower )) && allowed+="$LOWER"
|
||||
(( use_digits )) && allowed+="$DIGIT"
|
||||
(( use_symbols ))&& allowed+="$SYMS"
|
||||
|
||||
# if nothing selected, default to alnum
|
||||
if [[ -z "$allowed" ]]; then
|
||||
allowed="$UPPER$LOWER$DIGIT"
|
||||
fi
|
||||
|
||||
# remove any user-excluded chars from allowed (do this via tr to avoid globbing issues)
|
||||
if [[ -n "$exclude" ]]; then
|
||||
# printf each char of allowed, delete excluded via tr, then reassemble
|
||||
allowed="$(printf %s "$allowed" | tr -d "$exclude")"
|
||||
fi
|
||||
|
||||
# final check
|
||||
if [[ -z "$allowed" ]]; then
|
||||
echo "passgen: allowed set is empty after exclusions; loosen options." >&2
|
||||
return 2
|
||||
fi
|
||||
|
||||
# helper: generate one password meeting optional strict policy
|
||||
_gen_one() {
|
||||
local need_upper=$use_upper
|
||||
local need_lower=$use_lower
|
||||
local need_digit=$use_digits
|
||||
local need_symbol=$use_symbols
|
||||
local out=""
|
||||
|
||||
# seed with at least one of each selected class if --strict
|
||||
if (( strict )); then
|
||||
if (( need_upper )); then out+="${UPPER:RANDOM%${#UPPER}:1}"; fi
|
||||
if (( need_lower )); then out+="${LOWER:RANDOM%${#LOWER}:1}"; fi
|
||||
if (( need_digit )); then out+="${DIGIT:RANDOM%${#DIGIT}:1}"; fi
|
||||
if (( need_symbol )); then out+="${SYMS:RANDOM%${#SYMS}:1}"; fi
|
||||
fi
|
||||
|
||||
# fill the rest from the full allowed set, using /dev/urandom
|
||||
local needed=$(( length - ${#out} ))
|
||||
if (( needed > 0 )); then
|
||||
# draw more than needed, then cut (helps when exclusions reduce size)
|
||||
local draw=$(( needed * 3 ))
|
||||
local extra="$(LC_ALL=C tr -dc "$allowed" </dev/urandom | head -c "$draw")"
|
||||
out+="${extra:0:needed}"
|
||||
fi
|
||||
|
||||
# If exclusions or strict left us short (very rare), top-up in a loop.
|
||||
while (( ${#out} < length )); do
|
||||
out+=$(LC_ALL=C tr -dc "$allowed" </dev/urandom | head -c 1)
|
||||
done
|
||||
|
||||
# FisherYates shuffle so strict-class seeds aren't predictable up front
|
||||
local i j tmp arr=()
|
||||
for (( i=0; i<length; i++ )); do arr[i]="${out:i:1}"; done
|
||||
for (( i=length-1; i>0; i-- )); do
|
||||
# get a random index j using bytes from /dev/urandom
|
||||
j=$(( $(od -An -N2 -tu2 < /dev/urandom) % (i+1) ))
|
||||
tmp=${arr[i]}; arr[i]=${arr[j]}; arr[j]=$tmp
|
||||
done
|
||||
printf "%s" "${arr[*]}" | tr -d ' '
|
||||
}
|
||||
|
||||
# generate the requested count
|
||||
local i
|
||||
for (( i=1; i<=count; i++ )); do
|
||||
_gen_one
|
||||
printf "\n"
|
||||
done
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user