如何在此密码生成器中仅生成一个特殊字符

如何在此密码生成器中仅生成一个特殊字符

我有一个命令可以生成带有多个特殊字符的密码。我怎样才能让它只生成1个特殊字符?

# Generate a random password
#  $1 = number of characters; defaults to 32
#  $2 = include special characters; 1 = yes, 0 = no; defaults to 1
function randpass() {
  [ "$2" == "0" ] && CHAR="[:alnum:]" || CHAR="[:graph:]"
    cat /dev/urandom | tr -cd "$CHAR" | head -c ${1:-32}
    echo
}

答案1

这里有几种方法:

1. 不断迭代,直到获得您“喜欢”的密码

while true
do
    word=$(tr -cd "[:graph:]" < /dev/urandom | head -c ${1:-32})
    if [[ "$word" =~ [[:punct:]].*[[:punct:]] ]]
    then
        echo "$word has multiple special characters - reject."
        continue
    fi
    if [[ "$word" =~ [[:punct:]] ]]
    then
        echo "$word has one special character - accept."
        break
    fi
    echo "$word has no special characters - reject."
    continue
done

警告:对于大量字符(例如,> 16),这可能需要很长时间。

2. 读到一个标点符号后停止

n=${1:-32}
if [ "$2" == "0" ]
then
    CHAR="[:alnum:]"
else
    CHAR="[:graph:]"
fi
word=
for ((i=0; i<n; i++))
do
    thischar=$(tr -cd "$CHAR" < /dev/urandom | head -c 1)
    if ! [[ "$thischar" =~ [[:alnum:]] ]]
                            # Probably equivalent to if [[ "$thischar" =~ [[:punct:]] ]]
    then
        # Got one special character – don’t allow any more.
        echo "$thischar is a special character."
        CHAR="[:alnum:]"
    fi
    word="$word$thischar"
done
echo "$word"

请注意,这会获取前三个中的特殊字符(例如,ab!defghijklmnopqrstuvwxyz123456非常 经常。此外,理论上可以使用这种方法获得没有特殊字符的密码。

答案2

我想我会[:alnum:]先生成 32 个字符,然后选择性地插入一个特殊字符:

function randpass() {
  passwd=$( < /dev/urandom tr -cd "[:alnum:]" | head -c $1)
  if [ "$2" == "0" ]; then
    echo "$passwd"
  else
    spchar=$( < /dev/urandom tr -cd "[:punct:]" | head -c 1)
    pos=$((RANDOM%$1))
    echo "${passwd:0:pos}${spchar}${passwd:pos+1:$1}"
  fi
}

我假设包含[:punct:]您认为“特殊”的所有字符。

语法$(( ))shell算术扩展它生成一个 0 到 31 之间的随机数(或任何数字$1)。

语法${var:offset:length}shell参数扩展从字符串返回子字符串。

答案3

只需将head命令更改为-c 1

# Generate a random password
#  $1 = number of characters; defaults to 32
#  $2 = include special characters; 1 = yes, 0 = no; defaults to 1
function randpass() {
  [ "$2" == "0" ] && CHAR="[:alnum:]" || CHAR="[:graph:]"
    cat /dev/urandom | tr -cd "$CHAR" | head -c 1
    echo
}

相关内容