我正在尝试创建一个密码生成器,生成8到16个字符之间的密码。它还必须包含一个数字和小写和大写字母,以及生成时随机放置在字符串中的一个特殊字符。
目前,我的代码有时会给我一个不符合要求的密码,例如。 AOKOKKK@1
(无小写字母)此外,我还需要帮助才能使特殊符号只在密码中出现一次。我该如何解决这个问题?
这是我的代码:
length=$[ 8 +$[RANDOM % 16]]
char=(0 1 2 3 4 5 6 7 8 9 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 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 ! @ \# $ % ^ \&)
max=${#char[*]}
for ((i = 1; i <= $length ; i++))do
let rand=${RANDOM}%${max}
password="${password}${char[$rand]}"
done
echo $password
答案 0 :(得分:11)
这保证了一个且只有一个特殊字符,以及至少一个数字,小写和大写字母。要在密码中随机放置这些字符,sort -R
用于在打印密码之前加扰字符的顺序:
#!/bin/bash
choose() { echo ${1:RANDOM%${#1}:1}; }
{
choose '!@#$%^\&'
choose '0123456789'
choose 'abcdefghijklmnopqrstuvwxyz'
choose 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i in $( seq 1 $(( 4 + RANDOM % 8 )) )
do
choose '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
done
} | sort -R | tr -d '\n'
echo ""
我们定义了一个便利功能:
choose() { echo ${1:RANDOM%${#1}:1}; }
choose
接受一个参数,一个字符串,然后从该字符串中随机选择一个字符。
我们在每个所需类型的字符之一的每一行打印一个字符:
choose '!@#$%^\&'
choose '0123456789'
choose 'abcdefghijklmnopqrstuvwxyz'
choose 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
我们打印所需的剩余字符数,每行一个字符。这些字符是从数字,小写和大写字母中随机选择的:
for i in $( seq 1 $(( 4 + RANDOM % 8 )) )
do
choose '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
done
从上面开始,特殊字符始终是第一个,数字是第二个,等等。我们需要随机化。我们使用sort -R
执行此操作:
sort -R | tr -d '\n'
tr -d '\n'
用于从字符之间删除换行符,从而在一行中生成一串字符。
在评论中,JonathanLeffer表明sort -R
的输出并非完全随机。 sort -R
对每行的哈希值进行排序。显然添加了随机种子,但每行都接收相同的种子。为了解决这个问题,下面的版本在每一行都提供了自己的种子。这是通过更改choose
函数来完成的。最后,awk
用于删除这些数字并显示完整的密码:
#!/bin/bash
choose() { echo ${1:RANDOM%${#1}:1} $RANDOM; }
{
choose '!@#$%^\&'
choose '0123456789'
choose 'abcdefghijklmnopqrstuvwxyz'
choose 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i in $( seq 1 $(( 4 + RANDOM % 8 )) )
do
choose '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
done
} | sort -R | awk '{printf "%s",$1}'
echo ""
在awk
中,每一行都分为字段。第一个字段是随机选择的字母,而第二个字段是我们为种子散列添加的随机数。语句printf "%s",$1
打印第一个字段(没有尾随空格)并忽略第二个字段。最终结果是我们想要的密码。
要将输出捕获到变量,我们使用命令替换:
choose() { echo ${1:RANDOM%${#1}:1} $RANDOM; }
pass="$({ choose '!@#$%^\&'
choose '0123456789'
choose 'abcdefghijklmnopqrstuvwxyz'
choose 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i in $( seq 1 $(( 4 + RANDOM % 8 )) )
do
choose '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
done
} | sort -R | awk '{printf "%s",$1}')"
命令替换,由$(...)
表示,运行parens中的命令并捕获它们的标准输出。
答案 1 :(得分:2)
pwgen默认安装在某些Linux发行版(尤其是Ubuntu)上,并且还有一个Windows版本。为什么不使用它?
答案 2 :(得分:0)
#!/bin/bash
#Password Generator Script
echo "Password Generator Script"
read -p "Enter the password lenght: " PASS_LENGTH
for VAR in $(seq 1 3); #how many times password will generate, you can set range
do
openssl rand -base64 48 | cut -c1-$PASS_LENGTH
#-base64(Encode) 48 is length
#cut is for user input column -c1 is column1
done
答案 3 :(得分:0)
我使用 pwmake 设置为 128 位来执行此操作。对于大多数发行版,它都是开箱即用的,并使用 /dev/urandom 生成好的密码。