随机密码生成器 Bash
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26665389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Random Password Generator Bash
提问by Jeremy
I am trying to make a password generator that generates a password between 8-16 characters. It also has to contain a digit and lower and uppercase letters, as well as only one special character that is randomly placed in the string when being generated.
我正在尝试制作一个密码生成器,可以生成 8-16 个字符之间的密码。它还必须包含一个数字和大小写字母,以及在生成时随机放置在字符串中的一个特殊字符。
At the moment, my code will sometimes give me a password that does not meet the requirements eg. AOKOKKK@1
(no lowercase letters) In addition, I also need help to make it so that the special symbol only appears once in the password. How can I fix this?
目前,我的代码有时会给我一个不符合要求的密码,例如。AOKOKKK@1
(没有小写字母)此外,我还需要帮助使特殊符号在密码中只出现一次。我怎样才能解决这个问题?
Here's my code:
这是我的代码:
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
回答by John1024
This guarantees one and only one special characters, as well as at least one of digits, lower case, and upper case. To place those characters randomly within the password, sort -R
is used to scramble the order of characters before the password is printed:
这保证了一个且只有一个特殊字符,以及数字、小写和大写中的至少一个。将这些字符随机放置在密码中,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 ""
How it works
这个怎么运作
We define a convenience function:
choose() { echo ${1:RANDOM%${#1}:1}; }
choose
takes one argument, a string, and randomly selects a character from that string.We print one character per line of one of each of the required types of characters:
choose '!@#$%^\&' choose '0123456789' choose 'abcdefghijklmnopqrstuvwxyz' choose 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
We print the remaining number of characters needed, one character per line. These characters are selected randomly from digits, lower case, and upper case:
for i in $( seq 1 $(( 4 + RANDOM % 8 )) ) do choose '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' done
From the above, the special character is always first and the digit second, etc. We need to randomize. We do that with
sort -R
:sort -R | tr -d '\n'
tr -d '\n'
serves to removes the newlines from between the characters, resulting in a string of characters on one line.
我们定义了一个便利函数:
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'
用于删除字符之间的换行符,从而在一行中生成一串字符。
Improvement
改进
In the comments, JonathanLeffer shows that the output of sort -R
is not fully random. sort -R
sorts on a hash of each line. Apparently a random seed is added but each line receives the same seed. To get around this, the version below provides its own seed on each line. This is done by a change to the choose
function. At the end, awk
is used to remove those numbers and display the complete password:
在评论中,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",}'
echo ""
In awk
, each line is divided into fields. The first field is the randomly chosen letter while the second is the random number that we added to seed the hash. The statement printf "%s",$1
prints the first field (with no trailing whitespace) and ignores the second field. The end result is the password that we want.
在 中awk
,每行都分为字段。第一个字段是随机选择的字母,而第二个字段是我们添加的随机数以播种散列。该语句printf "%s",$1
打印第一个字段(没有尾随空格)并忽略第二个字段。最终结果是我们想要的密码。
Capturing the password to a variable
将密码捕获到变量
To capture the output to a variable, we use command substitution:
要将输出捕获到变量,我们使用命令替换:
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",}')"
Command substitution, denoted by $(...)
, runs the commands in the parens and captures their stdout.
用 表示的命令替换$(...)
运行括号中的命令并捕获它们的标准输出。
回答by whereswalden
回答by angdev
#!/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