检查数组bash中的单个字符是否为密码生成器

时间:2016-04-10 01:55:35

标签: arrays bash random

我正在尝试使用密码规则测试用户输入。

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

我正在尝试如何将用户字符串与包含密码字符的数组进行比较。

=

我的问题:

  1. 我无法让#!/bin/bash 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""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=("&""@""#""$""%""*""-""+""=") # Password Generator PassGen(){ # generate password if no user input Pwlength=`shuf -i 8-16 -n 1` # holds the range/length of password 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" echo exit? } # I want to make the following to work : \#PassGen2(){ # generate password 2 if no user input \#if [ $# -eq 0 ] ; then \#for ((i=0;i<4;i++)) \#do \#password="${Upper[$random % ${#Upper[@]}" ] } \#password="${Lower[$random % ${#Lower[@]}" ] } \#password="${Numbers[$random % ${#Numbers[@]}" ] } \#done \#password="${SpecialChar[$random % ${#SpecialChar[@]}" ] } \#password="${Upper[$random % ${#Upper[@]}" ] } \#echo "Random Password is being generated for you" \#sleep 5 \#echo "Your new password is : $Password" \#fi \#echo exit? \#} # Help menu Usage(){ # Help menu echo "The password must meet the following :" echo "> must be at least 8 characters long but not longer than 16 characters." echo "> must contain at least 1 digit (0-9)." echo "> must contain at least 1 lowercase letter." echo "> must contain at least 1 uppercase letter." echo "> must contain exactly one and only one of @ # $ % & * + - =" echo "" echo " * * IF NO PASSWORD IS ENTERED THE SYSTEM WILL GENERATE A PASSPORD FOR YOU * * " echo exit? } #The main starts here if [ $# -eq 0 ] ; then PassGen $SpecialChar fi if [ $# == "-h"] ; then Usage fi UserPW=$1 # assigning the firsth positional parameter to variable (password) #The reason I open the post PwCheck(){ if [[ ${#UserPW} < 8 && ${#UserPW} > 0 ]] ;then #check the lower end of the password echo "Password have to be more then 8 character" exit 1 fi if [[ ${#UserPW} < 16 ]] ;then #checks if the password bigger then 16 character echo "Password too long ! - Password have to be between 8 - 16 characters" exit 1 fi if [[ ${#UserPW} < 17 && ${#UserPW} > 8 ]] ; then Pwarr=($UserPW) # putting the variable into Array for (( i=0; i < ${#Upper[@]};i++ )) do if [[ ${Pwarr[0]:[i]:1} != ${Upper[i]} ]]; then echo "You have to enter at least 1 upper character letter" exit 1 fi done for (( i=0; i < ${#Lower[@]};i++ )) do if [[ ${Pwarr[0]:[i]:1} != ${Lower[i] ]]; then echo "You have to enter at least 1 Lower character letter" exit 1 fi done for (( i=0; i < ${#SpecialChar[@];i++ )) do if [[ ${Pwarr[0]:[i]:1} != ${SpecialChar[i] ]] ;then echo " You have to enter at least 1 special character exit 1 fi done #} 在“呼唤它”旁边工作。我知道 必须有拼写错误或语法错误。
  2. 对于PassGen2()功能,我知道我没有把它和IF称为 声明应在主要部分。

1 个答案:

答案 0 :(得分:1)

实现PwCheck更容易,将用户密码保留为字符串而不是将其转换为数组:

bad_length(){
  l=`wc -c`
  [ $l -ge 8 ] && [ $l -le 16 ] && return 1 || return 0
}

no_digit(){
  grep -q '[0-9]' && return 1 || return 0
}

no_lc(){
  grep -q '[a-z]' && return 1 || return 0
}

no_uc(){
  grep -q '[A-Z]' && return 1 || return 0
}

specials='@#$%&*+=-'
no_exactly_one_special(){
  n=`grep -o "[$specials]" | wc -l`
  [ $n -eq 1 ] && return 1 || return 0
}

echo "$1" | bad_length && echo 'Password must be between 8 - 16 characters' && exit 1
echo "$1" | no_digit && echo 'Password must have at least one number 0-9' && exit 1
echo "$1" | no_lc && echo 'Password must have at least one lowercase letter' && exit 1
echo "$1" | no_uc && echo 'Password must have at least one UPPERCASE letter' && exit 1
echo "$1" | no_exactly_one_special && echo "Password must have exactly one special character: $specials" && exit 1
exit 0

几句解释:

首先,bash可以将(使用|)传递给函数:

no_digit_from_stdin(){
  grep -q '[0-9]' && return 1 || return 0
}
echo "abc" | no_digit_from_stdin && echo $?

而不是将其作为参数传递:

no_digit_from_arg(){
  echo "$1" | grep -q '[0-9]' && return 1 || return 0
}
no_digit_from_arg "abc" && echo $?

这两个在这里有相同的结果。

其次,可以使用管道和&amp;&amp;简洁地控制流程。所以这个:

echo "$1" | no_digit_from_stdin && echo 'Password must have at least one number 0-9' && exit 1

与此结果相同:

if no_digit_from_arg "$1"; then
   echo 'Password must have at least one number 0-9'
   exit 1
fi

......但这些都是风格问题,与你的问题没有直接关系。

以下是我的答案版本,您可能会发现更多可用的秘密奖励功能:

PwCheck(){

    pass=true

    l=`echo "$UserPW" | wc -c`
    if [ $l -lt 8 ] || [ $l -gt 16 ]; then
        echo 'Password must be between 8 - 16 characters'
        pass=false
    fi

    if ! echo "$UserPW" | grep -q '[0-9]'; then
        echo 'Password must have at least one number 0-9'
        pass=false
    fi

    if ! echo "$UserPW" | grep -q '[a-z]'; then
        echo 'Password must have at least one lowercase letter'
        pass=false
    fi

    if echo "$UserPW" | grep -q '[A-Z]'; then
        echo 'Password must have at least one UPPERCASE letter'
        pass=false
    fi

    specials='@#$%&*+=-'
    n=`echo "$UserPW" | grep -o "[$specials]" | wc -l`
    if [ $n -ne 1 ]; then
        echo "Password must have exactly one special character: $specials"
        pass=false
    fi

    if $pass; then
        exit 0
    else
        exit 1
    fi
}