我需要一种按照以下要求生成随机密码的方法:
- 密码至少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
,只是不能使用大括号扩展和类似的范围。
但是您可以明确地一一列出它们,并引用它们以保护它们免受 shell 的影响:
shuf -r -n2 -e '!' '"' '#' '$' % '&' '(' ')' '*' + , - . / : ';' '<' = '>' '?' @ '[' '\' ']' '^' _ '{' '|' '}'
或者将它们放入字符串中并使用分词将它们放入多个参数中。不过,需要禁用 globbing 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 Cat 提供的解决方案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' )