como gerar apenas um caractere especial neste gerador de senhas

1

Eu tenho um comando que gera senha com vários caracteres especiais. Como posso gerar apenas 1 caractere especial?

# 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
}
    
por user3395201 19.09.2014 / 20:06

3 respostas

1

Aqui estão algumas abordagens:

1. Iterar até obter uma senha que você "goste"

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

Aviso: isso pode levar muito tempo para um grande número de caracteres (por exemplo, > 16).

2. Pare depois de receber um caractere de pontuação

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"

Observe que isso recebe o caractere especial nos três primeiros (por exemplo, ab!defghijklmnopqrstuvwxyz123456 ) muito com frequência. Além disso, é teoricamente possível obter uma senha sem caracteres especiais usando essa abordagem.

    
por 19.09.2014 / 22:45
1

Acho que geraria 32% dos caracteres[:alnum:] primeiro e depois, opcionalmente, inseriria um caractere especial:

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
}

Eu assumo que [:punct:] contém todos os caracteres que você considera "especiais".

A sintaxe $(( )) é uma expansão aritmética da shell que gera uma número aleatório entre 0 e 31 (ou qualquer que seja o $1 ).

A sintaxe ${var:offset:length} é uma expansão do parâmetro shell para retorna uma substring de uma string.

    
por 19.09.2014 / 22:44
0

Basta alterar o comando head para -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
}
    
por 19.09.2014 / 20:15