Unstable password, is there a better way to generate passwords? - python

import random
import string
lowercase = [string.ascii_lowercase]
uppercase = [string.ascii_uppercase]
number = [string.digits]
symbols = [string.punctuation]
password_outputs = string.ascii_lowercase + string.ascii_uppercase + string.digits +string.punctuation
I was wondering if there was a better way to create a more secure password then just using the ascii strings with random

Done following changes in your code.
import random
import string
lowercase = [string.ascii_lowercase]
uppercase = [string.ascii_uppercase]
number = [string.digits]
symbols = [string.punctuation]
password_outputs = string.ascii_lowercase + string.ascii_uppercase + string.digits +string.punctuation
print("Welcome to the RPG!")
gen_password=''
stop = False
num_char = 0. # include this line if you want that earlier user entered 3 and in next iteration 5 so total you want 8 character password if you only want 5 character password then you can remove this line
while not stop:
gen_password='' # each time it will default to empty
num_char += int(input('Enter in the ammount of characters for the desired password: '))
while num_char > 0:
rand_char = random.choice(password_outputs)
gen_password += rand_char
num_char -= 1
#basically a redstone repeater that decreases in value until it hits 0 and can contiue. User able to pick start value
if num_char == 0:
print(gen_password)
#ensures that only the final product of while loop is printed
#if num_char != int:
#stop = False
#want to make it more secure against non-integer inputs, not sure how to go about this
user_continue = input('Would you like to generate a longer password? (y/n): ')
if user_continue == 'y':
stop = False
elif user_continue == 'n':
stop = True
else:
print('Invalid Operation, running generator again')
stop = False
print("Have a nice day!")

Related

Where is my mistake? Checking if password is correct in Python

I am new in Python and programming. I am trying to make a program that verifies that the entered password has a certain format. I was pretty sure my code was correct, but obviously...it's not. It won't exit the while loop when the password is in the correct format.
Where is my mistake? Thank you all for your patience!
low = ['abcdefghijklmnopqrstuvwxyz']
up = ['ABCDEFGHIJKLMNOPQRSTUVWXYZ']
cr = ['#$%&']
digito = ['0123456789']
counter1 = 0
tries = True
while tries:
length = False
May = False
Minus = False
Num = False
Char = False
counter1 += 1
password = input('Password: ')
if len(password) > 7 and len(password) < 16:
length = True
for caracter in password:
if caracter in low:
Minus = True
if caracter in up:
May = True
if caracter in cr:
Char = True
if caracter in digito:
Num = True
if length and May and Minus and Num and Char:
print('Password ok.')
passw = password
tries = False
if counter1 == 5:
print('You had 5 attemps.')
break
The issue is that when you check:
"A" in ['ABCDEFGHIJKLMNOPQRSTUVWXYZ']
it returns False. This is because the list ['ABCDEFGHIJKLMNOPQRSTUVWXYZ'] does not contain the element "A". Try to replace the top 4 line with the following code and see if it works:
low = 'abcdefghijklmnopqrstuvwxyz'
up = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
cr = '#$%&'
digito = '0123456789'
low, up, cr and digito should all be strings, not a list with only one string in it: low = 'abcdefghijklmnopqrstuvwxyz'. Otherwise only literally "abcdefghijklmnopqrstuvwxyz" is in low, not "a".
Each list should contain separate letters instead of an entire string of the alphabet.
For example, instead of writing
up = ['ABCDEFGHIJKLMNOPQRSTUVWXYZ']
you should write
up = ['A','B','C','D','E','F','G'...]
A better version of your code might be the following:
tries = True
up = False
low = False
special = False
counter = 0
while tries:
counter += 1
if counter == 5:
print('You had 5 attemps.')
break
password = input("Enter your password: ")
if len(password) > 7 and len(password) < 16:
for char in password:
if char.upper() == char:
up = True
if char.lower() == char:
low = True
if (ord(char) >= 35 and ord(char) <= 38) or ord(char) == 64:
special = True
if up and low and special:
tries = False
print("Password ok")

input isn't choosing the passwort length

I'm new to programming, and I'm making a password manager.
My problem: -what it does -> when I run the program and enter the length of the password it generates a password, but it is always 4 digits long and the password gets repeated so many times as the digit I had put in.
-What it should do -> the digit that I put in should determine the length of the password and not how many times it gets repeated.
import random
#shuffle the list
def shuffle(string):
tempList = list(string)
random.shuffle(tempList)
return ''.join(tempList)
#the password functions
uppercaseLetter=chr(random.randint(65,90))
lowercaseLetter=chr(random.randint(97,122))
punctuationSign=chr(random.randint(32,152))
digit=chr(random.randint(48,57))
#completing the password
passwordLength = int(input("choose your password length: "))
possibleChars = uppercaseLetter, lowercaseLetter, punctuationSign, digit
ranChar = shuffle(possibleChars)
tempPassword = []
count = 0
while count != passwordLength:
tempPassword.extend(ranChar)
count = count + 1
password = ''.join(tempPassword)
#for which sitename
sitename = input('Save under which name: ')
print (password, sitename)
data=open("test.txt",'a')
data.write(sitename +' ')
data.write(password +'\n')
data.close()
I think you are really over complicating what you need to do, here is what you're trying to do to the best of my knowledge
import random
#completing the password
passwordLength = int(input("choose your password length: "))
temp_pass = ''
count = 0
while count != passwordLength:
char_type = random.randint(0,3)
if char_type == 0:
random_char = chr(random.randint(65,90))
elif char_type == 1:
random_char = chr(random.randint(97,122))
elif char_type == 2:
random_char = chr(random.randint(32,152))
else:
random_char = chr(random.randint(48,57))
temp_pass = temp_pass + random_char
count = count + 1
print(temp_pass)
Hope this helps. I would advise practicing the basics more before trying things like this, there is a lot of bad practises in the code.

Python how to check if input is a letter or character

How can I check if input is a letter or character in Python?
Input should be amount of numbers user wants to check.
Then program should check if input given by user belongs to tribonacci sequence (0,1,2 are given in task) and in case user enter something different than integer, program should continue to run.
n = int(input("How many numbers do you want to check:"))
x = 0
def tribonnaci(n):
sequence = (0, 1, 2, 3)
a, b, c, d = sequence
while n > d:
d = a + b + c
a = b
b = c
c = d
return d
while x < n:
num = input("Number to check:")
if num == "":
print("FAIL. Give number:")
elif int(num) <= -1:
print(num+"\tFAIL. Number is minus")
elif int(num) == 0:
print(num+"\tYES")
elif int(num) == 1:
print(num+"\tYES")
elif int(num) == 2:
print(num+"\tYES")
else:
if tribonnaci(int(num)) == int(num):
print(num+"\tYES")
else:
print(num+"\tNO")
x = x + 1
You can use num.isnumeric() function that will return You "True" if input is number and "False" if input is not number.
>>> x = raw_input()
12345
>>> x.isdigit()
True
You can also use try/catch:
try:
val = int(num)
except ValueError:
print("Not an int!")
For your use, using the .isdigit() method is what you want.
For a given string, such as an input, you can call string.isdigit() which will return True if the string is only made up of numbers and False if the string is made up of anything else or is empty.
To validate, you can use an if statement to check if the input is a number or not.
n = input("Enter a number")
if n.isdigit():
# rest of program
else:
# ask for input again
I suggest doing this validation when the user is inputting the numbers to be checked as well. As an empty string "" causes .isdigit() to return False, you won't need a separate validation case for it.
If you would like to know more about string methods, you can check out https://www.quackit.com/python/reference/python_3_string_methods.cfm which provides information on each method and gives examples of each.
This question keeps coming up in one form or another. Here's a broader response.
## Code to check if user input is letter, integer, float or string.
#Prompting user for input.
userInput = input("Please enter a number, character or string: ")
while not userInput:
userInput = input("Input cannot be empty. Please enter a number, character or string: ")
#Creating function to check user's input
inputType = '' #See: https://stackoverflow.com/questions/53584768/python-change-how-do-i-make-local-variable-global
def inputType():
global inputType
def typeCheck():
global inputType
try:
float(userInput) #First check for numeric. If this trips, program will move to except.
if float(userInput).is_integer() == True: #Checking if integer
inputType = 'an integer'
else:
inputType = 'a float' #Note: n.0 is considered an integer, not float
except:
if len(userInput) == 1: #Strictly speaking, this is not really required.
if userInput.isalpha() == True:
inputType = 'a letter'
else:
inputType = 'a special character'
else:
inputLength = len(userInput)
if userInput.isalpha() == True:
inputType = 'a character string of length ' + str(inputLength)
elif userInput.isalnum() == True:
inputType = 'an alphanumeric string of length ' + str(inputLength)
else:
inputType = 'a string of length ' + str(inputLength) + ' with at least one special character'
#Calling function
typeCheck()
print(f"Your input, '{userInput}', is {inputType}.")
If using int, as I am, then I just check if it is > 0; so 0 will fail as well. Here I check if it is > -1 because it is in an if statement and I do not want 0 to fail.
try:
if not int(data[find]) > -1:
raise(ValueError('This is not-a-number'))
except:
return
just a reminder.
You can check the type of the input in a manner like this:
num = eval(input("Number to check:"))
if isinstance(num, int):
if num < 0:
print(num+"\tFAIL. Number is minus")
elif tribonnaci(num) == num: # it would be clean if this function also checks for the initial correct answers.
print(num + '\tYES')
else:
print(num + '\NO')
else:
print('FAIL, give number')
and if not an int was given it is wrong so you can state that the input is wrong. You could do the same for your initial n = int(input("How many numbers do you want to check:")) call, this will fail if it cannot evaluate to an int successfully and crash your program.

Python brute force password guesser

I am doing a task in class about a password guesser. I stumbled into a lot of problems trying to solve this task, my first approach was to use for loops (code below), but I realized that the amount of 'for loops' is equal to the length of the string.
a_z = 'abcdefghijklmnopqrstuvwxyz'
pasw = 'dog'
tests = 0
guess = ''
azlen = len(a_z)
for i in range(azlen):
for j in range(azlen):
for k in range(azlen):
guess = a_z[i] + a_z[j] + a_z[k]
tests += 1
if guess == pasw:
print('Got "{}" after {} tests'.format(guess, str(tests)))
break
input()
The program above is very concrete. It only works if there are exactly 3 characters entered. I read that you could use a package called intertools, however, I really want to find another way of doing this. I thought about using recursion but don't even know where to start.
import string
import itertools
for possible_password in itertools.permutations(string.ascii_letters, 3):
print(possible_password)
If you don't want to use itertools you can certainly do this with recursion, which will work with passwords of any (reasonable) length—it's not wired to three characters. Basically, each recursive call will attempt to append a new character from your alphabet to your running value of guess. The base case is when the guess attains the same length as value you're seeking, in which case you check for a match. If a match is found, return an indication that you have succeeded (I used return True) so you can short circuit any further searching. Otherwise, return a failure indication (return False). The use of a global counter makes it a bit uglier, but produces the same results you reported.
ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
def brute_force_guesser(passwd, guess = ''):
global _bfg_counter
if len(guess) == 0:
_bfg_counter = 0
if len(guess) == len(passwd):
_bfg_counter += 1
if guess == passwd:
print('Got "{}" after {} tests'.format(guess, str(_bfg_counter)))
return True
return False
else:
for c in ALPHABET:
if brute_force_guesser(passwd, guess + c):
return True
return False
brute_force_guesser('dog') # => Got "dog" after 2399 tests
brute_force_guesser('doggy') # => Got "doggy" after 1621229 tests
One way to avoid the global counter is by using multiple return values:
ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
def brute_force_guesser(target, guess = '', counter = 0):
if len(guess) == len(target):
counter += 1
if guess == target:
print('Got "{}" after {} tests'.format(guess, str(counter)))
return True, counter
return False, counter
else:
for c in ALPHABET:
target_found, counter = brute_force_guesser(target, guess + c, counter)
if target_found:
return True, counter
return False, counter
brute_force_guesser('dog') # => Got "dog" after 2399 tests
brute_force_guesser('doggy') # => Got "doggy" after 1621229 tests
Here is my full answer, sorry if it's not neat, I'm still new to coding in general. The credit goes to #JohnColeman for the great idea of using bases.
import math
global guess
pasw = str(input('Input password: '))
chars = 'abcdefghijklmnopqrstuvwxyz' #only limeted myself to lowercase for simplllicity.
base = len(chars)+1
def cracker(pasw):
guess = ''
tests = 1
c = 0
m = 0
while True:
y = tests
while True:
c = y % base
m = math.floor((y - c) / base)
y = m
guess = chars[(c - 1)] + guess
print(guess)
if m == 0:
break
if guess == pasw:
print('Got "{}" after {} tests'.format(guess, str(tests)))
break
else:
tests += 1
guess = ''
cracker(pasw)
input()
import itertools
import string
def guess_password(real):
chars = string.ascii_lowercase + string.digits
attempts = 0
for password_length in range(1, 20):
for guess in itertools.product(chars, repeat=password_length):
attempts += 1
guess = ''.join(guess)
if guess == real:
return 'the password is {}, found in {} guesses.'.format(guess, attempts)
print(guess, attempts)
print(guess_password('abc'))

Validation of a Password - Python

So I have to create code that validate whether a password:
Is at least 8 characters long
Contains at least 1 number
Contains at least 1 capital letter
Here is the code:
def validate():
while True:
password = input("Enter a password: ")
if len(password) < 8:
print("Make sure your password is at lest 8 letters")
elif not password.isdigit():
print("Make sure your password has a number in it")
elif not password.isupper():
print("Make sure your password has a capital letter in it")
else:
print("Your password seems fine")
break
validate()
I'm not sure what is wrong, but when I enter a password that has a number - it keeps telling me that I need a password with a number in it. Any solutions?
You can use re module for regular expressions.
With it your code would look like this:
import re
def validate():
while True:
password = raw_input("Enter a password: ")
if len(password) < 8:
print("Make sure your password is at lest 8 letters")
elif re.search('[0-9]',password) is None:
print("Make sure your password has a number in it")
elif re.search('[A-Z]',password) is None:
print("Make sure your password has a capital letter in it")
else:
print("Your password seems fine")
break
validate()
r_p = re.compile('^(?=\S{6,20}$)(?=.*?\d)(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[^A-Za-z\s0-9])')
this code will validate your password with :
min length is 6 and max length is 20
at least include a digit number,
at least a upcase and a lowcase letter
at least a special characters
password.isdigit() does not check if the password contains a digit, it checks all the characters according to:
str.isdigit(): Return true if all characters in the string are digits
and there is at least one character, false otherwise.
password.isupper() does not check if the password has a capital in it, it checks all the characters according to:
str.isupper(): Return true if all cased characters in the string are
uppercase and there is at least one cased character, false otherwise.
For a solution, please check the question and accepted answer at check if a string contains a number.
You can build your own hasNumbers()-function (Copied from linked question):
def hasNumbers(inputString):
return any(char.isdigit() for char in inputString)
and a hasUpper()-function:
def hasUpper(inputString):
return any(char.isupper() for char in inputString)
Example:
class Password:
def __init__(self, password):
self.password = password
def validate(self):
vals = {
'Password must contain an uppercase letter.': lambda s: any(x.isupper() for x in s),
'Password must contain a lowercase letter.': lambda s: any(x.islower() for x in s),
'Password must contain a digit.': lambda s: any(x.isdigit() for x in s),
'Password must be at least 8 characters.': lambda s: len(s) >= 8,
'Password cannot contain white spaces.': lambda s: not any(x.isspace() for x in s)
}
valid = True
for n, val in vals.items():
if not val(self.password):
valid = False
return n
return valid
def compare(self, password2):
if self.password == password2:
return True
if __name__ == '__main__':
input_password = input('Insert Password: ')
input_password2 = input('Repeat Password: ')
p = Password(input_password)
if p.validate() is True:
if p.compare(input_password2) is True:
print('OK')
else:
print(p.validate())
You are checking isdigit and isupper methods on the entire password string object not on each character of the string. The following is a function which checks if the password meets your specific requirements. It does not use any regex stuff. It also prints all the defects of the entered password.
#!/usr/bin/python3
def passwd_check(passwd):
"""Check if the password is valid.
This function checks the following conditions
if its length is greater than 6 and less than 8
if it has at least one uppercase letter
if it has at least one lowercase letter
if it has at least one numeral
if it has any of the required special symbols
"""
SpecialSym=['$','#','#']
return_val=True
if len(passwd) < 6:
print('the length of password should be at least 6 char long')
return_val=False
if len(passwd) > 8:
print('the length of password should be not be greater than 8')
return_val=False
if not any(char.isdigit() for char in passwd):
print('the password should have at least one numeral')
return_val=False
if not any(char.isupper() for char in passwd):
print('the password should have at least one uppercase letter')
return_val=False
if not any(char.islower() for char in passwd):
print('the password should have at least one lowercase letter')
return_val=False
if not any(char in SpecialSym for char in passwd):
print('the password should have at least one of the symbols $##')
return_val=False
if return_val:
print('Ok')
return return_val
print(passwd_check.__doc__)
passwd = input('enter the password : ')
print(passwd_check(passwd))
''' Minimum length is 5;
- Maximum length is 10;
- Should contain at least one number;
- Should contain at least one special character (such as &, +, #, $, #, %, etc.);
- Should not contain spaces.
'''
import string
def checkPassword(inputStr):
if not len(inputStr):
print("Empty string was entered!")
exit(0)
else:
print("Input:","\"",inputStr,"\"")
if len(inputStr) < 5 or len(inputStr) > 10:
return False
countLetters = 0
countDigits = 0
countSpec = 0
countWS = 0
for i in inputStr:
if i in string.ascii_uppercase or i in string.ascii_lowercase:
countLetters += 1
if i in string.digits:
countDigits += 1
if i in string.punctuation:
countSpec += 1
if i in string.whitespace:
countWS += 1
if not countLetters:
return False
elif not countDigits:
return False
elif not countSpec:
return False
elif countWS:
return False
else:
return True
print("Output: ",checkPassword(input()))
With Regex
s = input("INPUT: ")
print("{}\n{}".format(s, 5 <= len(s) <= 10 and any(l in "0123456789" for l in s) and any(l in "!\"#$%&'()*+,-./:;<=>?#[\]^_`{|}~" for l in s) and not " " in s))
Module import
from string import digits, punctuation
def validate_password(p):
if not 5 <= len(p) <= 10:
return False
if not any(c in digits for c in p):
return False
if not any(c in punctuation for c in p):
return False
if ' ' in p:
return False
return True
for p in ('DJjkdklkl', 'John Doe'
, '$kldfjfd9'):
print(p, ': ', ('invalid', 'valid')[validate_password(p)], sep='')
Sure with regex there are easier answers, but this one of the simplest ways
from string import punctuation as p
s = 'Vishwasrocks#23' #or user input is welcome
lis = [0, 0, 0, 0]
for i in s:
if i.isupper():
lis[0] = 1
elif i.islower():
lis[1] = 1
elif i in p:
lis[2] = 1
elif i.isdigit():
lis[3] = 1
print('Valid') if 0 not in lis and len(s) > 8 else print('Invalid')
The simplest python validation using normal methods
password = '-'
while True:
password = input(' enter the passwword : ')
lenght = len(password)
while lenght < 6:
password = input('invalid , so type again : ')
if len(password)>6:
break
while not any(ele.isnumeric() for ele in password):
password = input('invalid , so type again : ')
while not any(ele.isupper() for ele in password):
password = input('invalid , so type again : ')
while not any(ele not in "[#_!#$%^&*()<>?/|}{~:]" for ele in password):
password = input('invalid , so type again : ')
break
isdigit() checks the whole string is a digit, not if the string contains a digit
Return true if all characters in the string are digits and there is at least one character, false otherwise.
isupper() checks the whole string is in uppercase, not if the string contains at least one uppercase character.
Return true if all cased characters in the string are uppercase and there is at least one cased character, false otherwise.
What you need is using the any built-in function:
any([x.isdigit() for x in password]) will return True if at least one digit is present in password
any([x.isupper() for x in password]) will return True if at least one character is considered as uppercase.
Maybe you can use regex expression:
re.search(r"[A-Z]", password)
Check uppercase letters.
re.search(r"[0-9]", password)
Check digits in password.
Python 2.7
The for loop will assign a condition number for each character. i.e. Pa$$w0rd in a list would = 1,2,4,4,2,3,2,2,5. Since sets only contains unique values, the set would = 1,2,3,4,5; therefore since all conditions are met the len of the set would = 5. if it was pa$$w the set would = 2,4 and len would = 2 therefore invalid
name = raw_input("Enter a Password: ")
list_pass=set()
special_char=['#','$','#']
for i in name:
if(i.isupper()):
list_pass.add('1')
elif (i.islower()):
list_pass.add('2')
elif(i.isdigit()) :
list_pass.add('3')
elif(i in special_char):
list_pass.add('4')
if len(name) >=6 and len(name) <=12:
list_pass.add('5')
if len(list_pass) is 5:
print ("Password valid")
else: print("Password invalid")
uppercase_letter = ['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']
number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
import re
info ={}
while True:
user_name = input('write your username: ')
if len(user_name) > 15:
print('username is too long(must be less than 16 character)')
elif len(user_name) < 3 :
print('username is short(must be more than 2 character)')
else:
print('your username is', user_name)
break
while True:
password= input('write your password: ')
if len(password) < 8 :
print('password is short(must be more than 7 character)')
elif len(password) > 20:
print('password is too long(must be less than 21 character)')
elif re.search(str(uppercase_letter), password ) is None :
print('Make sure your password has at least one uppercase letter in it')
elif re.search(str(number), password) is None :
print('Make sure your password has at least number in it')
else:
print('your password is', password)
break
info['user name'] = user_name
info['password'] = password
print(info)
Password Complexity conditions:
Must include at least one uppercase character
Must include at least one lowercase character
Must include at least one number
Must include at least one special character
Must have a length of at least 8 and a max of 20
import re
def validate():
while True:
password = raw_input("Enter a password: ")
re_exp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$!%*#?&])[A-Za-z\d#$!#%*?&]{8,20}$"
if re.search(re.compile(regex_exp),password):
print("Your password seems fine")
else:
print("Password doees not matches with password complexity conditions")
break
Or you can use this to check if it got at least one digit:
min(passwd).isdigit()

Categories

Resources