如何替换双循环?

时间:2017-12-17 09:46:13

标签: python while-loop

评估密码强度的程序最初检查密码的长度是否正确(6-12)以及密码是否包含扩展的ASCII字符,即127-255。

我遇到的问题是,如果用户首先输入的密码太短或太长,程序就不会检查下一个密码中的扩展字符,由用户输入,反之亦然,首先检查扩展字符。

我实现了一个双循环,如果这是正确的调用方式,但它仍然没有带来预期的效果。

import re
import time
#score variable, responsible for later defining if passwords is weak, medium or strong
Score = 0
#list for improvements to password printed out with score at the end
Improvements = []
Password = ""
#defines function for checking for presence of extended characters (i.e. ascii 128-255)
def hasExtended(s):
    return any(ord(i) > 127 for i in s)
#inputs password
Password = input("Please enter a password:")
Password_length = len(Password)
Extended_presence = hasExtended(Password)
#checks password length (6-12), asks user to re-input until password is within boundaries
#checks if password contains extended characters
#double while loops to allow for two conditions simultaneously
while Password_length < 6 or Password_length > 12:
    if Password_length < 6:
        Outputted_length = "too short"
        Outputted_criteria = "no shorter than 6 characters"
    else:
        Outputted_length = "too long"
        Outputted_criteria = "no longer than 12 characters"
    print("Your password is", Outputted_length, ". It has to be", Outputted_criteria, ".")
    Password = input("Please enter a password:")
    Password_length = len(Password)

    while Extended_presence:
        print("Your password contains characters from the extended ASCII list. Please don't use these.")
        Password = input("Please enter a password:")
        Extended_presence = hasExtended(Password)

while Extended_presence:
    print("Your password contains characters from the extended ASCII list. Please don't use these.")
    Password = input("Please enter a password:")
    Extended_presence = hasExtended(Password)

    while Password_length < 6 or Password_length > 12:
        if Password_length < 6:
            Outputted_length = "too short"
            Outputted_criteria = "no shorter than 6 characters"
        else:
            Outputted_length = "too long"
            Outputted_criteria = "no longer than 12 characters"
        print("Your password is", Outputted_length, ". It has to be", Outputted_criteria, ".")
        Password = input("Please enter a password:")
        Password_length = len(Password)
else:
    #defines function for checking for presence of numbers
    def hasNumbers(s):
        return any(i.isdigit() for i in s)
    #defines function for checking for presence of letters
    def hasLetters(s):
        return any(i.isalpha() for i in s)
    #defines function for checking for presence of special characters
    def hasSpecial(s):
        return any(ord(i) < 48 for i in s)
    #checks if password contains letters
    Letter_presence = hasLetters(Password)
    if not Letter_presence:
        Score = Score - 1
        Improvements.append("letters")
    else:
        Score = Score + 1
    #checks if password is all upper case
    Is_upper = Password.isupper()
    if not Is_upper:
        Score = Score + 1
    else:
        Score = Score - 1
        Improvements.append("upper and lower case letters")
    #checks if passwords is all lower case
    Is_lower = Password.islower()
    if not Is_lower:
        Score = Score + 1
    else:
        Score = Score - 1
        Improvements.append("upper and lower case letters")
    #checks if password contains a number
    Number_presence = hasNumbers(Password)
    if not Number_presence:
        Score = Score + 0
        Improvements.append("numbers")
    else:
        Score = Score + 1
    #checks if password is just numbers
    Only_numbers = Password.isdigit()
    if not Only_numbers:
        Score = Score + 0
    else:
        Score = Score - 1
        Improvements.append("other characters")
    #checks if password contains special characters
    Special_presence = hasSpecial(Password)
    if not Special_presence:
        Score = Score + 0
        Improvements.append("special characters, such as '$'")
    else:
        Score = Score + 1
    #outputs weak, medium or strong password to user and suggest improvements
    if Score <= 2:
        print("The program is processing your password...")
        time.sleep(2)
        print("Your password isn't acceptable! Please try again.")
        print("Next time, remember to include", Improvements)
    if Score == 3:
        print("The program is processing your password...")
        time.sleep(2)
        print("Your password is weak, you should try again.")
        print("Next time, remember to include", Improvements)
    elif Score == 4:
        print("The program is processing your password...")
        time.sleep(2)
        print("Your password is medium, it should be OK.")
        print("Next time, remember to include", Improvements)
    elif Score == 5:
        print("The program is processing your password...")
        time.sleep(2)
        print("Your password is strong, it is absolutely fine.")

4 个答案:

答案 0 :(得分:0)

尝试使用此代码,而不是在首次检查Extended_presence的编码时使用if,而不需要while,因为它已经在之前的while循环范围内:

import re
print([chr(i) for i in range(127,200)])

import re
import time
#score variable, responsible for later defining if passwords is weak, medium or strong
Score = 0
#list for improvements to password printed out with score at the end
Improvements = []
Password = ""
#defines function for checking for presence of extended characters (i.e. ascii 128-255)
def hasExtended(s):
    return any(ord(i) > 127 for i in s)
#inputs password
Password = input("Please enter a password:")
Password_length = len(Password)
Extended_presence = hasExtended(Password)
#checks password length (6-12), asks user to re-input until password is within boundaries
#checks if password contains extended characters
#double while loops to allow for two conditions simultaneously
while Password_length < 6 or Password_length > 12:
    if Password_length < 6:
        Outputted_length = "too short"
        Outputted_criteria = "no shorter than 6 characters"
    else:
        Outputted_length = "too long"
        Outputted_criteria = "no longer than 12 characters"
    print("Your password is", Outputted_length, ". It has to be", Outputted_criteria, ".")
    Password = input("Please enter a password:")
    Password_length = len(Password)

    if Extended_presence:
        print("Your password contains characters from the extended ASCII list. Please don't use these.")
        Password = input("Please enter a password:")
        Extended_presence = hasExtended(Password)

while Extended_presence:
    print("Your password contains characters from the extended ASCII list. Please don't use these.")
    Password = input("Please enter a password:")
    Extended_presence = hasExtended(Password)

输出:

Please enter a password:hel¢
Your password is too short . It has to be no shorter than 6 characters .
Please enter a password:hello¢
Your password contains characters from the extended ASCII list. Please don't use these.
Please enter a password:hello¢
Your password contains characters from the extended ASCII list. Please don't use these.
Please enter a password:hellllo#

答案 1 :(得分:0)

您可以实现以下方案: check_pass函数将检查函数的长度

def hasExtended(s):
    return any(ord(i) > 127 for i in s)

check_pass = lambda x: x>=6 and x<=12  # check for range of input value

password=input("Password: ")

if check_pass(len(password)) and not hasExtended(password):
    print("Valid password")
else:
    print("Do not use extended ascii characters, use password with minimum length of 6 and maximum length of 12")

更准确地说明您可以使用以下方式嵌套的错误:

if check_pass(len(password)) and not hasExtended(password):
    print("Valid password")
elif check_pass(len(password)) and hasExtended(password):
    print("do not use extended ascii character")
elif not check_pass(len(password)) and hasExtended(password):
    print("password length should be between 6 to 12")

同样如果你想分别检查最小长度和最大长度的无效长度。

如果您希望单独检查所有条件,然后显示成功或失败,您可以执行以下操作:

def verify_password(password):
    if len(password) < 6:
        print("require minimum 6 characters")
    if len(password) > 12:
        print("can not use more then 12 characters")
    if hasExtended(password):
        print("use only valid ascii characters")
    else:
        print("valid password")
        return True

while not verify_password(password): # loop will never stops unless valid password or used break statement within
    password = input("Password: ")

如果条件满足消息将被打印,该函数将检查三种不同的条件,否则它将继续执行,如果它是有效密码而不是打印任何东西它将打印有效密码并返回True而不是None

答案 2 :(得分:0)

我建议你写一个验证器,一个看起来像这样的函数:

class FirstController: UIViewController, UITextViewDelegate {

    fileprivate let textView: UITextView = {
        let textView = UITextView()
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.isEditable = false
        textView.isSelectable = true
        textView.textAlignment = .center
        textView.isScrollEnabled = true
        return textView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        textView.delegate = self

        configureTextView()
    }

    override func viewDidLayoutSubviews() {
        textView.setContentOffset(.zero, animated: false)
    }

    func configureTextView(){

        //textView anchors are set

        let firstPlainSent = "Read this first.\n"
        let secondPlainSent = "Read this second.\n"

        plainSentAttr = [NSFontAttributeName: UIFont(name: "Helvetica", size: 17)!, NSForegroundColorAttributeName: UIColor.black]

        let firstSent = NSAttributedString(string: firstPlainSent, attributes: plainSentAttr)
        let secondSent = NSAttributedString(string: secondPlainSent, attributes: plainSentAttr)

        let mutableAttributedString = NSMutableAttributedString()
        mutableAttributedString.append(firstSent)
        mutableAttributedString.append(secondSent)

        let tappableString = NSMutableAttributedString(string: "Click here to present the SecondVC\n\n")
        tappableString.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica", size: 17)!, range: NSMakeRange(0, (tappableString.length)))
        tappableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blue, range: NSMakeRange(0, (tappableString.length)))
        tappableString.addAttribute(NSUnderlineStyleAttributeName, value: 1, range:  NSMakeRange(0,tappableString.length))
        tappableString.addAttribute(NSUnderlineColorAttributeName, value: UIColor.blue, range: NSMakeRange(0, tappableString.length))
        tappableString.addAttribute(NSLinkAttributeName, value: "doSomething", range: NSMakeRange(0, (tappableString.length)))

        mutableAttributedString.append(tappableString)

        textView.attributedText = mutableAttributedString
    }


    func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {

        // I also tried URL.scheme
        if URL.absoluteString == "doSomething"{

            let secondVC = SecondController()
            let navVC = UINavigationController(rootViewController: secondVC)
            present(navVC, animated: true, completion: nil)
            return false
        }

        return true
    }
}

然后以类似的方式调用它:

def validate_password(password):
    ... # check score, symbols and other, print whatever you want
    return score

答案 3 :(得分:0)

为什么不将密码检查委派给某个功能并将用户输入与检查密码分开?这样,您可以根据需要多次询问用户,而无需复杂的跳转。类似的东西:

def validate_password(password):
    if len(password) < 6:
        return 0, "Your password is too short, it has to be no shorter than 6 characters."
    elif len(password) > 12:  # why, tho?
        return 0, "Your password is too long, it has to be no longer than 12 characters."
    # these can be optimized but I'll leave that as an exercise for you
    if any(ord(i) > 127 for i in password):  # again, why?!
        return 0, ("Your password contains characters from the extended ASCII list. "
                   "Please don't use these.")
    score = 0
    improvements = []
    if any(i.isalpha() for i in password):
        score += 1
        if password.isupper() or password.islower():
            score -= 1
            improvements.append("upper and lower case letters")
        else:
            score += 1
    else:
        score -= 1
        improvements.append("letters")
    if any(i.isdigit() for i in password):
        score += 1
        if password.isdigit():
            score -= 1
            improvements.append("other characters")
    else:
        # score -= 1   # are you sure you don't want to reduce the score?
        improvements.append("numbers")
    if any(ord(i) < 48 for i in password):
        score += 1
    else:
        # score -= 1   # are you sure you don't want to reduce the score?
        improvements.append("special characters such as '$'")
    return score, "Next time remember to include: {}".format(", ".join(improvements))

现在,您可以根据需要随时随地拨打电话:

while True:
    candidate = input("Please enter a password: ")
    print("The program is processing your password...")  # why? this happens in an instant
    score, message = validate_password(candidate)
    time.sleep(2)  # why are we making people wait for no reason?
    if score <= 1:
        print(message)
        print("Please try again.")
    elif score == 2:
        print("Your password is weak, you should try again.")
        print(message)
    elif score == 3:
        print("Your password is medium, it should be OK.")
        print(message)
        break
    elif score == 4:
        print("Your password is strong, it is absolutely fine.")
        break

print("Accepted password: " + candidate)

你可以得到一个输出:

Please enter a password: dfld
The program is processing your password...
Your password is too short, it has to be no shorter than 6 characters.
Please try again.
Please enter a password: dfldsadlslads
The program is processing your password...
Your password is too long, it has to be no longer than 12 characters.
Please try again.
Please enter a password: dflds°
The program is processing your password...
Your password contains characters from the extended ASCII list. Please don't use these.
Please try again.
Please enter a password: ddlllsd
The program is processing your password...
Next time remember to include: upper and lower case letters, numbers, special characters
such as '$'
Please try again.
Please enter a password: ddlllsd12
The program is processing your password...
Next time remember to include: upper and lower case letters, special characters such as '$'
Please try again.
Please enter a password: Ddlllsd12
The program is processing your password...
Your password is medium, it should be OK.
Next time remember to include: special characters such as '$'
Accepted password: Ddlllsd12