Мне нужен способ генерации случайного пароля, отвечающего следующим требованиям:
- Пароль не менее 9 символов
- не менее 2 заглавных букв
- не менее 2 строчных букв
- не менее 2 цифр
- не менее 2 специальных символов
- должно начинаться с буквы
Вот команда, которая у меня есть:
{ shuf -r -n4 -e {A..Z}; shuf -r -n4 -e {a..z}; shuf -r -n4 -e {0..9}; } | shuf | tr -d $'\n'
но отсутствуют специальные символы
ОС — SuSE 12
решение1
Вы можете добавить специальные символы с помощью другого shuf
, просто нельзя использовать расширение фигурных скобок и подобные диапазоны.
Но вы можете явно перечислить их, один за другим, заключив в кавычки, чтобы защитить их от оболочки:
shuf -r -n2 -e '!' '"' '#' '$' % '&' '(' ')' '*' + , - . / : ';' '<' = '>' '?' @ '[' '\' ']' '^' _ '{' '|' '}'
Или засунуть их в строку и использовать разделение слов, чтобы поместить их в несколько аргументов. set -f
Однако нужно отключить подстановку с помощью , иначе звездочка вызовет проблемы:
set -f
shuf -r -n2 -e $(sed -e 's/./& /g' <<< '!"#$%&()*+,-./:;<=>?@[\]^_{|}' )
(или просто сделайте то, что делают все, и добавьте два фиксированных специальных символа в конец разумного пароля, который и без них достаточно длинный.)
Чтобы убедиться, что у вас есть буква в качестве первого символа, проще всего просто добавить одну отдельно и перемешать символы только остальной части пароля. Например, это создаст пароль из двух частей, первая из которых будет одной буквой (в верхнем или нижнем регистре), вторая — это то, что вы указали в комментариях:
#!/bin/bash
set -f
pw=$(shuf -r -n1 -e {A..Z} {a..z})
pw="$pw$( { shuf -r -n4 -e {A..Z}; shuf -r -n4 -e {a..z}; shuf -r -n4 -e {0..9}; shuf -r -n2 -e $(sed -e 's/./& /g' <<< '@%+\/!#$^?:.(){}[]-_.'); } | shuf | tr -d '\n' )"
echo "$pw"
Вывод будет примерно таким:
$ bash pw.sh
WRgpJ7pP%Tj60.1
$ bash pw.sh
oV6N#7s4Po3Bt)r
решение2
Взгляни наКак сгенерировать случайную строку?
Герберт предлагает использовать/dev/urandom
tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 13 ; echo
400 Кот предлагает решение сopenssl
openssl rand -base64 12
Проблема в том, что ни одно из этих решений не гарантирует, что у вас будут все необходимые символы (т. е. 2 цифры, 2 специальных символа и т. д.).
Используя shuf
и основываясь на вашем исходном коде, вы можете сделать что-то вроде
shuf -r -n1 -e {a..z} {A..Z} | tr -d $'\n'; { shuf -r -n2 -e {0..9}; shuf -r -n2 -e {a..z}; shuf -r -n2 -e {A..Z}; shuf -r -n2 -e { \! \" \# $ % \& '\' '/' \( \) \{ \} [ ] \< \> + - = . , : \; ? @ \| \` \~ ^ _ "'" \* }; } | shuf | tr -d $'\n'
Разделено на строки для удобства чтения:
shuf -r -n1 -e {a..z} {A..Z} | tr -d $'\n';
{ shuf -r -n2 -e {0..9};
shuf -r -n2 -e {a..z};
shuf -r -n2 -e {A..Z};
shuf -r -n2 -e { \! \" \# $ % \& '\' '/' \( \) \{ \} [ ] \< \> + - = . , : \; ? @ \| \` \~ ^ _ "'" \* }; } | shuf | tr -d $'\n'
Что создаст строку, начинающуюся с буквы (обратите внимание, что я не пересылаю первую строку в последнюю shuf
) и содержащую 2 строчные буквы, 2 заглавные буквы и 2 цифры (всего 9 символов).
решение3
В конце концов, это финальная команда:
export PASSWORD=$(shuf -r -n1 -e {A..Z} {a..z})$( { shuf -r -n4 -e {A..Z}; shuf -r -n4 -e {a..z}; shuf -r -n4 -e {0..9}; shuf -r -n2 -e $(sed -e 's/./& /g' <<< '@%+\/!#$^?:.(){}[]-_.'); } | shuf | tr -d '\n' )