#!/usr/bin/env bash # 生成随机密码 # $1 为指定位数,缺省为 10 位 create_passwd() { local length="${1:-10}" if ! [[ "$length" =~ ^[0-9]+$ ]]; then echo "Error: length must be an integer." >&2 return 1 fi if (( length < 4 )); then echo "Error: Password length must be at least 4." >&2 return 1 fi # 固定 ASCII 语义,避免 locale 影响 export LC_ALL=C # 字符集(去除易混淆字符: 0, O, 1, l, I) local -r digits="23456789" local -r lower="abcdefghijkmnpqrstuvwxyz" local -r upper="ABCDEFGHJKMNPQRSTUVWXYZ" local -r symbols="!@#$%^&*()-+=[]{}|;:,.<>?" local -r all_chars="${digits}${lower}${upper}${symbols}" # 从 charset 均匀取 1 个字符:拒绝采样,避免取模偏差 rand_char() { local charset="$1" local -i clen=${#charset} local -i limit=$(( 256 - (256 % clen) )) # 仅接受 [0, limit-1] local b idx while :; do b=$(od -An -N1 -tu1 < /dev/urandom | tr -d ' ') (( b < limit )) || continue idx=$(( b % clen )) printf '%s' "${charset:idx:1}" return 0 done } local passwd="" # 强制复杂度:每类至少 1 个(全程 /dev/urandom) passwd+="$(rand_char "$digits")" passwd+="$(rand_char "$lower")" passwd+="$(rand_char "$upper")" passwd+="$(rand_char "$symbols")" # 填充剩余 local -i remaining=$(( length - 4 )) for ((i=0; i