我正在尝试构建一个脚本,其中我需要创建一个具有以下参数的密码生成器:
- 长度必须至少为8个字符,但不得超过16个字符
- 必须至少包含1个数字(0-9)
- 必须至少包含一个小写字母
- 必须至少包含一个大写字母
- 必须仅包含一个
@ # $ % & * + - =
我有两个想法:
第一:
#!/bin/bash
#
#Password Generator
#
#
Upper=('A''B''C''D''E''F''G''H''I''J'K''L''M''N''O''P''Q''R''S''T''U''V''W''X''Y''Z')
Lower=('a''b''c''d''e''z''f''g''h''i''j''k''l''m''o'''p''q''r''s''t''u''v''w''x''y''z')
Numbers=('1''2''3''4''5''6''7''8''9')
SpecialChar=('@''#''$''%''&''*''+''-''=')
if [ S# -eq 0 ] ; then
Pwlength=`shuf -i 8-16 -n 1`
Password=`< /dev/urandom tr -dc A-Za-z0-9$SpecialChar | head -c $Pwlength`
echo "Random Password is being generated for you"
sleep 5
echo "Your new password is : $Password"
exit
问题是我得到了我甚至没有定义的角色?
第二个想法:
for((i=0;i<4;i++))
do
password=${Upper[$random % ${#Lower[@]} ] }
password=${Upper[$random % ${#Upper[@]} ] }
password=${Upper[$random % ${#Number[@]} ] }
password=${Upper[$random % ${#SpecialChar[@]} ] }
done
由于某种原因,他们都不工作;/
在第一个示例中,将"-"字符移动到SpecialChar。我认为您的定义允许"+"到"="(即,传递给tr的值读作"+-="),这说明了您没有预料到的字符。或者,将"-"替换为"_"。
So, try a definition like:
SpecialChar=('@''#''$''%''&''*''+''=''-')
-
如前所述,直接使用字符串来处理字符列表会更干净、更容易。处理数组中的特殊字符可能会产生副作用(例如,获取当前目录中带有"*"字符的文件列表)。此外,数组可能很难作为函数参数传递)。
ALPHA_LOW="abcdefghijklmnopqrstuvwxyz" # Then simply access the char in the string at the ith position CHAR=${ALPHA_LOW:$i:1}
-
您可以从小写中生成大写。
ALPHA_UP="`echo "$ALPHA_LOW" | tr '[:lower:]' '[:upper:]'`"
-
包含随机数的变量为
$RANDOM
(大写)。 -
CCD_ 3是不必要的。
-
您需要找到一种方法来保持每个字符类型的出现次数。为了了解更多信息,我写了一个完整的脚本来做你在这里描述的事情。
您的第一次尝试出现以下问题:
- 您正在使用数组来包含单个字符串。粘贴
'A''B''C'
相当于粘贴'ABC'
。简单地将这些转换为标量变量可能是最简单的解决方案 - 你没有引用你的变量
- 您声明了
Upper
、Lower
和Numbers
,但从不使用它们 - 不管怎样,为你只使用过一次(或更少:-)的东西使用变量是可疑的
- 正如@KevinO所指出的,短划线在
tr
中有着特殊的含义,如果你想从字面上匹配它,它需要是第一个或最后一个
最重要的是,sleep 5
似乎没有任何有用的用途,如果还没有,它会开始让你烦恼。如果你真的想要一台较慢的电脑,我相信这里有人愿意交易。
您的第二次尝试出现以下问题:
- Bash中的特殊变量
$RANDOM
以大写字母拼写 - 您正在尝试对(未引用的!)字符数组执行模运算,这是定义不明确的。
%
之后的除数需要是单个整数。您可以将字符代码转换为整数,但这有点痛苦,而且还不清楚您希望得到什么结果
修复第一次尝试的快速尝试是
Password=$(< /dev/urandom tr -dc 'A-Za-z0-9@#$%&*+=-' | head -c $(shuf -i 8-16 -n 1))
如果您想验证生成的密码上的一些属性,我仍然不明白为什么需要数组。
while read -r category expression; do
case $Password in
*[$expression]*) continue;;
*) echo "No $category"; break;;
esac
done <<'____HERE'
lowercase a-z
uppercase A-Z
numbers 0-9
specials -@#$%&*+=
HERE