I am creating a program that checks passwords to see if they are strong enough:
they need caps,
lower case,
numbers,
symbols and
cannot contain easy passwords.
As you can see below this is only some of my code and I have a menu, and a password checker, the only problem is that the checker doesn't seem to be working as when I enter a password, its always saying its a strong password even though it does not contain any caps or numbers or symbols. Below is my code so far.
import random #importing random
import time #importing time
global Menu
def Menu():
global optionchoice #globalising variable optionchoice so that it can be used inside of another def of the code
print("Hey, Welcome to PassWordChecker.")
time.sleep(2) #delaying the next line for 2 seconds
print("Please choose one of the options below." )
time.sleep(1)
print("MENU:")
print("***")
print(" press 1 once for : password checker ")
print(" press 2 twice for : password generator")
print(" press 3 two or three times to : Quit ")
print(" ***") #creating a basic menu
optionchoice = (input("which option would you like to choose?"))
def checkpasswordandinput():
global optionchoice
optionchoice = optionchoice
if optionchoice == '1':
print(" please enter a password. ")
UserPassword = input("")
if len(UserPassword) <= 8 or len(UserPassword) >= 24 or UserPassword == UserPassword.isupper() or UserPassword == UserPassword.isdigit() or UserPassword == UserPassword.islower() or UserPassword == UserPassword.isalpha():
print("make sure your password includes numbers and upper and lower case letters ")
UserPassword = input('please enter a new password')
else:
print('your password is a very good one that is difficult to crack')
return Menu()
Notes to future readers:
Please do not write code in the form above:
Do not import modules you don't need
Do not use global variables
Do use loops: eg while True:
Do call functions from other functions
Do return values from one function back to the caller: optionchoice = menu()
The above code would have been better in this form:
import time
def menu():
print(" press 1 for password checker ")
print(" press 2 for password generator")
print(" press 3 to Quit")
return input("which option would you like to choose?")
def checkpasswordandinput():
while True:
optionchoice = menu()
if optionchoice == '1':
#Enter password and validate
pass
# detect other options
if optionchoice == '3':
break
checkpasswordandinput()
Those checks in the form UserPassword == UserPassword.isupper() will not work. Here, you are comparing a string, the password, to a boolean, the result of isX(). Hence, all those checks are False and you get to the else branch (if the length is acceptable).
In the case of upper and lowercase chars, you could use UserPassword == UserPassword.upper() instead (just upper, not isupper, and analogously with lower()), i.e. compare the password to it's upper/lowercased version, but for digits this does not work. Instead, you can use any to check if any char is a digit: any(c.isdigit() for c in UserPassword)
Edit: You can use UserPassword == UserPassword.upper() to check if the password does not contains any lowercase letters, which is kind of unintuitive. Instead, I'd suggest using any for all the checks and also inversing the condition so the "positive" case is in the ifs body and the "negative" in the else. Something like this:
up = UserPassword
if 8 <= len(up) <= 24 and any(c.isupper() for c in up) and any(c.islower() for c in up) and any(c.isdigit() for c in up) and any(c.isalpha() for c in up):
Or a bit shorter, using a list of functions:
if 8 <= len(up) <= 24 and all(any(f(c) for c in up) for f in (str.islower, str.isupper, str.isdigit, str.isalpha)):
So you need to do something like the following:
hasUpper = False
hasLower = False
hasDigit = False
etc etc
Then, go through the 'password' one character at a time:
ie. string[1], string[2], string[3]
Run your boolean result on it (isupper, islower, etc)
when true, change your hasUpper, hasLower, hasDigit to True
Then, once gone through the whole string, check your boolean results with your requirements. ie:
if requirements are upper, lower, and digit.
if hasUpper = True and hasLower = True and hasDigit = True:
then it's a good password, etc.
Make sense?
Related
I am trying to code a simple random word generator and I am having issues with the while loop. When I run the code it asks the user for a strong or weak password. Strong will generate 14 random characters and weak will combine two words from a list. After choosing a password it will ask if you another password and if yes it will ask the question again. But when I run it once it asks for another password but it asks choose a strong/weak 2 times instead of asking for another password.
def randpasswd(length, chars=None):
if chars == None:
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%ยจ&*()_+/*\\|<>;:"
password = ""
for i in range(length):
password += random.choice(chars)
return password
def choosing():
choose = input("Choose strong or weak password: ")
a = ["password", "crash", "intel", "working"]
if choose == "strong":
print(randpasswd(14))
if choose == "weak":
print(''.join(random.choices(a, k=2)))
while True:
choosing()
done = input("Do you want another password? ")
if done == "yes":
choosing()
elif done == "no":
print("password is set")
break
Replace
if done == "yes":
choosing()
with
if done == "yes":
continue
so instead of
choosing() being run,
followed by the elif branch that would not be taken (since the other branch was taken),
followed by the loop starting over,
control just skips back to the start of the while True loop, where choosing() will be run anyway. (pass would do here too instead of continue, but the latter is more explicit.)
Replace your current while loop with this:
want_another = "yes"
while want_another != "no":
if want_another == "yes":
choosing()
want_another = input("Do you want another password? ")
print("password is set")
Right now, done is very badly named, since done is "no" when you are done and "yes" when you are not done.
Background:
I have made a program that takes a text input, applies encryption (a simple cipher) and saves the output to a list - if desired. Messages can also be decrypted.
The program is navigated through an options menu:
1. Encrypt a message
2. View encrypted messages
3. Decrypt a message
To allow all sections of the program to access the same list (variable) of saved messages, I have written it within a class. Within the class exist def's that call on this list.
Only the 'encrypt a message' bit has been written so far.
Problem:
The user decision flow is made with two Y/N choices.
However, the choices do not work - even if the user types in 'N' - my program thinks they have typed 'Y' in both cases.
def encrypt():
def save_cip():#This function allows the user to save the ciphered message to the ciphered_messages if they choose
choosing = True
while choosing:
save_choice = input("Would you like to save your Ciphered message? (Y/N)\n")
if save_choice == "Y" or "y":
print("You chose yes")
cct.ciphered_messages.append(' '.join(["Message", str(len(cct.ciphered_messages)), ":", cipher]))
choosing = False
elif save_choice == "N" or "n":
print("You chose no")
choosing = False
continue
else:
print("That was not a valid entry, please enter Y or N only")
continue
I think the problem lay within the scope, and that somehow the same variable is not being referenced when setting and reading Y or N. I have been going up and down the same code for about 3 hours and still nothing, declaring all variables in many different places with no luck, so any advice greatly appreciated.
Full executable code:
class cct:
print("Welcome to the CaeserCipher tool v1.0")
menu_state = "main" #This is used to record what state the program is in
unciphered_messages = [] #Decrypted messages are saved here
ciphered_messages = [] #Encrypted messages are saved here
def menu(): #This is the main menu interface
while cct.menu_state == "main": #This while
cct.menu_state = input("What would you like to do? \n 1: Encrypt a Message \n 2: View Encrypted Messages \n 3: Decrypt a message\n")
if cct.menu_state == "1":
cct.encrypt()
elif cct.menu_state == "2":
cct.view()
elif cct.menu_state == "3":
cct.decrypt()
elif cct.menu_state == "main":
print("\n\nWelcome back to the menu!\n\n")
else:
print("You did not enter a valid choice. Please enter a number between 1 and 3.\n")
cct.menu_state = "make_choice"
continue
def encrypt():
def save_cip():#This function allows the user to save the ciphered message to the ciphered_messages if they choose
choosing = True
while choosing:
save_choice = input("Would you like to save your Ciphered message? (Y/N)\n")
if save_choice == "Y" or "y":
print("You chose yes")
cct.ciphered_messages.append(' '.join(["Message", str(len(cct.ciphered_messages)), ":", cipher]))
choosing = False
elif save_choice == "N" or "n":
print("You chose no")
choosing = False
continue
else:
print("That was not a valid entry, please enter Y or N only")
continue
#This while loop continually takes messages, gives the option of saving, and asks if you want to cipher another
while cct.menu_state == "1":
text = input("Enter your message: ") #Enter the message you wish to cipher
cipher = '' #Create a string for the cipher
for char in text: #This for sub-loop will increment each character by 1. e.g. A -> B, T -> U, Z -> A
if not char.isalpha():
continue
char = char.upper()
code = ord(char) + 1
if code > ord('Z'):
code = ord('A')
cipher += chr(code)
print(' '.join(["Your ciphered message is:", cipher]))
save_cip()
print(cct.ciphered_messages)
#This sub-while loop is reponsible for checking if you want to cipher another message
#and making sure the user has made a valid choice
choosing_another = True
while choosing_another == True:
choice_variable = input(' '.join(["You have", str(len(cct.ciphered_messages)), "saved messages \n", "Would you like to Cipher another? (Y/N)\n"]))
if choice_variable == "Y" or "y":
print("You chose yes")
choosing_another = False
elif choice_variable == "N" or "n":
print("You chose no")
cct.menu_state = "main"
choosing_another = False
else:
choice_variable = input("That was not a valid entry, please enter Y or N only: \n")
continue
return
def view():
#TO BE CODED
return
def decrypt():
#TO BE CODED
return
cct.menu()
This is always true:
if save_choice == "Y" or "y":
bacause its interpreted as :
if (condition) or (condition):
the 1st condition is (save_choice == "Y")
the 2nd condition is just ( "y" ) which python interprets as 'True'
So the whole condition is always True.
U probably mean:
if save_choice == "Y" or save_choice == "y":
Or better :
if save_choice.lower() == "y":
Not a python programmer, but i don't think python allows a "implied" subject for the or operator
--> IF save_choice == "Y" OR save_choice == "y" :
I am doing a basic Python assessment on a password vault but am getting errors that I can't seem to solve myself. and btw guys I didn't come here for a grammar and punctuation lesson, so if you are just here to edit my question and not offer any assistance please dont bother.
For example, in this part of the code I want the user to input 1 or 2, and if he selects 1 it asks him to log in, while if he selects 2 it asks him to register. But at the moment it is completely ignoring the parameters and accepting anything.
Another problem is that when the user enters the valid password, instead of just stopping at password correct, it for some reason re-asks "what is your username."
while True:
login_orsignup1 = input('''Press
1) to Log in
2) to register a new account
''')
if login_orsignup1 != 1:
while True:
username = input('''What is your,
Username: ''')
if input_username == username:
l_p = input('''What is your password ''')
while True:
if l_p == input_lockerpassword:
print("Password Correct")
break
login_originup1()
----------------------------------------------------------#Full code begins now
l_p = ""
print("------------------------------------------------------------------------")
print('''Welcome to password Locker, a place where you can
store all your passwords to easily enter your precious accounts without
hassle.''')
print("------------------------------------------------------------------------")
print('''First lets make an account,''')
while True:
first_name = input('''What is your first name?
''')
if first_name.isdigit(): #isdigit, detects if there
print("Please enter a valid answer, No nubers shoud be present")
elif first_name == "":
print("Please enter an answer")
#the continue code skips the boundries within the loop and carries on with the connected program until it is succesfully met
else:
break #the break loop exits the current loop and continues with the next programes following it
while True:
sur_name = input('''What is your surname?
''')
if sur_name.isdigit(): #isdigit detects if the
print("No numbers")
elif sur_name == "":
print("Please enter an answer")
#the continue code skips the boundries within the loop and carries on with the connected program until it is succesfully met
else:
break
print('''------------------------------------------------------------------------''')
print('''Welcome, {} {}
what would you like your username to be, it should be something
memorable and no longer than fifteen characters long, '''.format(first_name, sur_name))
while True:
input_username = input("")
if 0 < len(input_username) < 16:
print('''Nice, username''')
break
elif input_username == "":
print("Please enter an answer")
else:
print('''Your username should be a maximum of 15 charecters, ''')
print('''-------------------------------------------------------------------------''')
while True:
input_lockerpassword = input('''Now it's time to setup a password for your locker, It should be between 4
and 10 charecters long,
''')
if len(input_lockerpassword) > 4 and len(input_lockerpassword) < 11:
print('''{}, is locked in thanks for joining Password Locker'''.format(input_lockerpassword))
break
else:
print("It should be between 4 and 10 charecters long!")
print('''
-------------------------------------------------------------------------------------------''')
def login_originup1():
print(''' Welcome to password vault, You can either login or create a New account''')
while True:
login_orsignup1 = input('''Press
1) to Log in
2) to register a new account
''')
if login_orsignup1 != 1:
while True:
username = input('''What is your,
Username: ''')
if input_username == username:
l_p = input('''What is your password ''')
while True:
if l_p == input_lockerpassword:
print("Password Correct")
break
login_originup1()```
Ok, first of all, you should know that the input() function returns a string and, as such, your first condition : if login_orsignup1 != 1 will always be true, because the string object '1' isn't equal to the int object 1. As for why you get asked again for the user after having a good password, that is because the break statement only breaks from the current loop. So you only break of this loop to get back at the start of your username verification loop. I would suggest a cleaner implementation like so :
# login or sign-up loop
while True:
login_orsignup1 = input(" Press \n1) to Log in \n2) to register a new account")
# you can have the input result in a variable like so, if you want to use it later on
if login_orsignup1 == "1": # you said '1' was for login, right?
# or you can test this directly in your if statement
# if it is only needed for this condition
while input("What is your username: ") != username:
print("Incorrect username")
# same thing for password, but could be implemented another way if you
# don't want to loop until the user gets the correct password
while input("What is your password: ") != input_lockerpassword:
print("Incorrect password for this username")
# your code gets here only if the user entered the right credentials
# so you can now break of the login or sign-up loop
break
elif login_orsignup1 == "2":
# code for registration here
This could be good enough for a simple thing. I would recommend designing this console program by following concepts of a state-machine and adding more code at each step to handle cases like going back one step or back at the start.
Hope this helps
the problem is in your login_originup1 function you are making three While loops that the program can't escape from in your function you are asking if login_orsignup1 != 1
without an else statement so if the user wanted to login he would press input in "1" then the program will say that
"1" =! 1 is false
it will look for an else statement But not find one so it will go back to the start of the loop and ask the user to input again. this is it for the First Loop.
Now if the user Inputs in "2" (which means that the user wants to register) it will make him log-in because:
"2" =! 1is true
and will continue to the next while loop in here you will be asking for the username and the user will give the username. Now this is it for the Second Loop
we now go to the last loop where you ask for the Password and the User Will give the Password. The program Will either 1. say that it was false and ask for the password again or 2. it will accept the password and Break the While loop. Now this is it for the Third Loop
so why is it asking me for the Username Because the break statement breaks only the while loop it is in so that break statement broke only the third while loop and was back to the Second Loop which the Second Loop will bring us back into the Third Loop again
so how to fix this?
simple like this:
def login_originup1():
print('Welcome to password vault, You can either login or create a New account')
while True:
login_orsignu = input('Press\n1) to Log in\n2) to register a new account\n')
loopBreaker = 0
if loopBreaker:
break
if int(login_orsignu) != 1:
while True:
if loopBreaker:
break
username = input('What is your,\nUsername:')
if input_username == username:
l_p = input('What is your password ')
while True:
if loopBreaker:
break
if l_p == input_lockerpassword:
print("Password Correct")
loopBreaker = 1
break
from pad4pi import rpi_gpio
# Setup Keypad
KEYPAD = [
["1","2","3","A"],
["4","5","6","B"],
["7","8","9","C"],
["*","0","#","D"]
]
ROW_PINS = [5,6,13,19] # BCM numbering
COL_PINS = [26,16,20,21] # BCM numbering
factory = rpi_gpio.KeypadFactory()
keypad = factory.create_keypad(keypad=KEYPAD, row_pins=ROW_PINS, col_pins=COL_PINS)
def processKey(key):
print("enter 3 digit")
print(key)
if key == 123:
print("correct")
else:
print("wrong password")
keypad.registerKeyPressHandler(processKey)
I want the code to wait for the user enter for example 3 digits before comparing with the password in the code which is 123 in above code.
What it should do:
Wait user enter 3 digit from the keypad , for example 123 , then print correct.
What it actually do:
it will print correct or incorrect password straight away after user enter 1 digit code
Update for raspberry taking #furas example:
# Initial keypad setup
code = ''
def processKey(key):
print("Enter your 3 digit PWD: \n")
global code
MAX_ALLOWED_CHAR = 3
code += key
if (len(code) == MAX_ALLOWED_CHAR):
if (code == "123"):
print("You entered the correct code.")
dostuff()
else:
code = ''
print("The passcode you entered is wrong, retry.")
def dostuff():
# do your things here since passcode is correct.
This might do it for your case.
def processKey():
key = input("enter 3 digit")
if (key == "123"):
print("Correct password.")
return True
else:
print("You typed {0} wich is incorrect.".format(key))
return False
So now you don't give processKey a value because as you said the user input it, calling processKey() will ask the user to enter a password and return true/false based on the "123" in the check.
This is if you want to input the password, but if the following answer is not suiting your needs (didn't quite fully understand what you want to accomplish) just provide more clever example.
Edit:
Since you wanted to strictly have a 3 digit input and a re-input password in case they enter the wrong one you can do the following:
On the call to processKey() you can:
while (processKey() == False):
processKey()
Revisioned code to match your needs:
def processKey():
MAX_ALLOWED_CHAR = 3
key = input("Enter 3 digit PWD: \n")
if (key == 123):
print("Correct password.")
return True
elif (len(str(key)) > MAX_ALLOWED_CHAR):
print("The max allowed character is {0}, instead you entered {1}.".format(MAX_ALLOWED_CHAR,key))
return False
else:
print("You typed {0} wich is incorrect.".format(key))
return False
while (processKey() == False):
processKey()
Output:
Enter 3 digit PWD:
3333
The max allowed character is 3, instead you entered 3333.
Enter 3 digit PWD:
321
You typed 321 wich is incorrect.
Enter 3 digit PWD:
123
Correct password.
keypress is executed after every key press - and it is natural. You have to keep all keys on list or in string and check its length.
code = ''
def processKey(key):
global code
code += key
if len(code) == 3:
if code == "123":
print("correct")
else:
print("wrong password, try again")
code = ''
How can I link the second info() call to a text file ?
print("Hi,welcome to the multiple choice quiz")
def info ():
print("Firstly we would like to collect some personal details:-?")
name = input("Please enter your first name?")
surname =input ("please enter your surname?")
email_address = input ("please enter your email addres #.co.uk")
username = input (" Chose a username?")
password = input ("Enter a Password?")
validation()
def validation():
correct = 0
while correct == 0:
correct=input(" is the following data is correct ?")
if correct in ["Y,y"]:
print("Well done you have registered for the quiz")
elif correct in ["N,n"]:
info()
else:
info()
You might want to drop your while loop.
info() calls your validation. "if" the data is correct, you finish, "else" you just call info() again.
That is pretty much what you did already. maybe you wanted it to look more like this:
print("Hi, welcome to the multiple choice quiz")
def info ():
print("Firstly we would like to collect some personal details:-?")
name = input("Please enter your first name?")
surname = input("please enter your surname?")
email_address = input("please enter your email address #.co.uk")
username = input(" Chose a username?")
password = input("Enter a Password?")
validation()
def validation():
correct = 0
correct = input(" is the data is correct ?")
if correct in ["Y,y"]:
print("Well done you have registered for the quiz")
elif correct in ["Y,y"]:
info()
else:
print "please type y or n"
validation()
info()
You wrote:
if correct in ["Y,y"]:
print("Well done you have registered for the quiz")
elif correct in ["N,n"]:
info()
else:
info()
Firstly, correct in ["Y,y"] will not do what you expect. ["Y,y"] is a list containing one element: "Y,y". That means correct in ["Y,y"] if and only if correct == "Y,y", and the user is not likely to enter that! You probably want a list with two elements: ["Y", "y"]. in can also test containment within strings, so you could use "Yy". You don't want a comma in there because then if the user enters just a comma that will pass the test as well, which is silly.
Putting that issue aside, if the user enters y or Y, it prints well done. If they enter n or N, info() is called. If they enter something else, info() is still called. That last part is surely not what you want: entering "N" and entering "A" should have different results! You want the user to be told that it's not valid. That part is easy, print a message. Then you want them to be asked again. Since they'll be asked for every iteration of your while loop, you just have to ensure that the loop continues. The loop will run as long as the condition correct == 0 is true, so just set correct to 0 and that will happen. So something like this:
else:
print("That's not valid")
correct = 0
OK, now to your question. You want to save those personal details to a file. You can't do that properly with the way your program is organised. The variables in info are local, so validation can't access them to save them. info has to do the saving (perhaps indirectly by passing the data along to another function). What we could do is have validation report the result of asking the user and let info decide what to do based on that:
def info ():
# collect data
if validation():
# save data
def validation():
correct = 0
while correct == 0:
correct=input(" is the following data is correct ?")
if correct in ["Y", "y"]:
print("Well done you have registered for the quiz")
return True
elif correct in ["N", "n"]:
return False
else:
print("That's not valid")
correct = 0
return will exit the validation function (thus ending the loop) and give the value returned to info to decide if the data should be saved.
Since the return statements end the loop, the only way the loop can continue is the else is reached, in which case explicitly making it continue with correct = 0 is silly. We can just make the loop go on forever until the function returns:
def validation():
while True:
correct=input(" is the following data is correct ?")
if correct in ["Y", "y"]:
print("Well done you have registered for the quiz")
return True
elif correct in ["N", "n"]:
info()
return False
else:
print("That's not valid")