【问题标题】:how to use RANDOM command in declared array如何在声明的数组中使用 RANDOM 命令
【发布时间】:2016-04-08 05:13:55
【问题描述】:

我正在尝试构建一个脚本,我需要使用以下参数创建密码生成器:

  • 必须至少有 8 个字符,但不能超过 16 个字符。
  • 必须至少包含 1 个数字 (0-9)。
  • 必须至少包含 1 个小写字母。
  • 必须至少包含 1 个大写字母。
  • 必须只包含@ # $ % & * + - =中的一个且仅一个

我有两个想法:

第一个:

#!/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

由于某种原因,它们都不起作用;/

【问题讨论】:

  • $RANDOM,不是$random
  • $SpecialChar 不会扩展到数组 "${SpecialChar[@]}" 的内容,并且因为它包含 shell 元字符,所以需要像我展示的那样使用双引号,以便 shell 不对这些元字符做出反应(展开任何通配符匹配等)。
  • 真的,sleep 5 的意义何在??
  • 无论如何,使用单个字符串的数组是非常没有意义的。去掉引号后,'A''B''C' 等价于'ABC'
  • :~/bin> 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")

标签: arrays bash password-generator


【解决方案1】:

在您的第一个示例中,将“-”字符移动到 SpecialChar 的末尾。我认为您的定义导致允许“+”到“=”(即,传递给 tr 的值读取为“+-=”),这说明了您不期望的字符。或者,将“-”替换为“_”。

So, try a definition like:
SpecialChar=('@''#''$''%''&''*''+''=''-')

【讨论】:

  • 您对特殊字符位置的看法是正确的。我做了一个改变,它现在可以工作了。关于另一种方法,我想了解我必须引用哪一部分?密码="${Upper[$random % ${#Upper[@]}" ] }
  • 我想使用 RANDOM 来混合数组中的字符并给我一个字符,该字符将被添加到“密码”变量中,我必须让它在 a 中遍历所有数组四次,所以我可以有 16 个字符
【解决方案2】:
  • 如前所述,直接使用字符串来处理字符列表会更简洁、更容易。处理数组中的特殊字符可能会导致副作用(例如获取当前目录中带有 '*' 字符的文件列表)。此外,数组可能难以作为函数参数传递)。

    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(大写字母)。

  • sleep 5 是不必要的。

  • 您需要找到一种方法来记录每种字符类型的剩余出现次数。有关更多信息,我编写了一个完整的脚本来执行您所描述的here

【讨论】:

【解决方案3】:

您的第一次尝试有以下问题:

  • 您正在使用数组来包含单个字符串。粘贴'A''B''C' 等同于'ABC'。简单地将这些转换为标量变量可能是最简单的解决方法。
  • 你不是quoting your variables
  • 您声明了UpperLowerNumbers,但从不使用它们。
  • 将变量用于只使用一次(或更少:-) 的东西无论如何都是值得怀疑的。
  • 正如@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

【讨论】:

  • 我声明了一个数组,因为稍后我必须对密码使用它来验证密码规则
  • 那么在初始化的时候,各个元素之间需要有空格。您的代码没有显示您如何尝试使用数组,所以不幸的是,我不知道如何修复这部分代码。 tr 在任何情况下都需要一个字符串。
  • 如果您当前的代码使用数组,实际上并没有,将其转换为使用常规标量可能仍然是最简单的解决方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 2020-01-28
  • 2019-03-29
  • 1970-01-01
相关资源
最近更新 更多