随机密码生成器Bash

时间:2014-10-30 23:50:55

标签: bash passwords

我正在尝试创建一个密码生成器,生成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

4 个答案:

答案 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 ""

如何运作

  1. 我们定义了一个便利功能:

    choose() { echo ${1:RANDOM%${#1}:1}; }
    

    choose接受一个参数,一个字符串,然后从该字符串中随机选择一个字符。

  2. 我们在每个所需类型的字符之一的每一行打印一个字符:

    choose '!@#$%^\&'
    choose '0123456789'
    choose 'abcdefghijklmnopqrstuvwxyz'
    choose 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    
  3. 我们打印所需的剩余字符数,每行一个字符。这些字符是从数字,小写和大写字母中随机选择的:

    for i in $( seq 1 $(( 4 + RANDOM % 8 )) )
    do
        choose '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    done
    
  4. 从上面开始,特殊字符始终是第一个,数字是第二个,等等。我们需要随机化。我们使用sort -R执行此操作:

    sort -R | tr -d '\n'
    

    tr -d '\n'用于从字符之间删除换行符,从而在一行中生成一串字符。

  5. 改进

    在评论中,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 生成好的密码。