Проверить пароль на надежность
Нужно написать функцию которая проверяет пароль: Критерии надежного пароля:
Длина строки пароля восемь символов. Содержит хотя бы одну букву в верхнем регистре. Содержит хотя бы одну букву в нижнем регистре. Содержит хотя бы одну цифру. Функция is_valid_password должна вернуть True, если переданный в качестве параметра пароль отвечает требованиям надежности. В противном случае вернуть False. мой код:
def is_valid_password(password):
b = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
c = "abcdefghijklmnopqrstuvwxyz"
d = "1234567890"
if len(password) >= 8:
for i in b:
for y in c:
for t in d:
if i and y and t in password:
return True
else:
return False
else:
return False
но когда is_valid_password('`ozal.2N') == False, а должно быть True,почему считает кавычки?
Ответы (4 шт):
я бы подправил логику и спрашивал бы содержится ли символ в определенном наборе, a результаты попаданий хранил бы в списке. После того как все символы строки пароля были проверены спросить все ли попадания существуют с помощью метода all()
import string
def is_valid_password(password):
if len(password) < 8:
return False
mass = [False, False, False]
for letter in password:
if letter in string.ascii_lowercase:
mass[0] = True
if letter in string.ascii_uppercase:
mass[1] = True
if letter in string.digits:
mass[2] = True
if all(mass):
return True
return False
Чтобы не перечислять символы и не писать вручную наборы, они уже существуют в string.
Разберём выражение i and y and t in password. Из таблицы приоритетов операторов следует что in имеет приоритет выше чем and и скобки надо расставить так: (i and y) and (t in password). В первой итерации цикла выражение вычисляется как ('A' and 'a') and ('1' in password). Оператор and значения 'A' и 'a' воспринимает как истину. Получаем значение '1' in password. Но единицы в пароле нет, поэтому выражение ложно.
Сколько раз выполняется тело цикла? Если условие истинно, цикл немедленно прерывается. Если условие ложно, тоже. То есть, ваш код равносилен следующему:
def is_valid_password(password):
if len(password) >= 8:
if 'A' and 'a' and '1' in password:
return True
else:
return False
else:
return False
Это нужно поправить. Если буквально следовать описанию то получится вот это:
def has_uppercase(password):
for c in password:
if c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
return True
return False
def has_lowercase(password):
for c in password:
if c in 'abcdefghijklmnopqrstuvwxyz':
return True
return False
def has_digit(password):
for c in password:
if c in '1234567890':
return True
return False
def is_valid_password(password):
# Длина строки пароля восемь символов.
if len(password) != 8:
return False
# Содержит хотя бы одну букву в верхнем регистре.
if not has_uppercase(password):
return False
# Содержит хотя бы одну букву в нижнем регистре.
if not has_lowercase(password):
return False
# Содержит хотя бы одну цифру.
if not has_digit(password):
return False
# Функция is_valid_password должна вернуть True,
# если переданный в качестве параметра пароль отвечает требованиям надежности.
return True
Функции has_... так похожи что их можно свести в одну:
def has_char(password, char_set):
for c in password:
if c in char_set:
return True
return False
def is_valid_password(password):
# Длина строки пароля восемь символов.
if len(password) != 8:
return False
# Содержит хотя бы одну букву в верхнем регистре.
if not has_char(password, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
return False
# Содержит хотя бы одну букву в нижнем регистре.
if not has_char(password, 'abcdefghijklmnopqrstuvwxyz'):
return False
# Содержит хотя бы одну цифру.
if not has_char(password, '1234567890'):
return False
# Функция is_valid_password должна вернуть True,
# если переданный в качестве параметра пароль отвечает требованиям надежности.
return True
Если вы заботитесь о производительности то желательно использовать множества:
upper_set = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
lower_set = set('abcdefghijklmnopqrstuvwxyz')
digit_set = set('1234567890')
def is_valid_password(password):
# Длина строки пароля восемь символов.
if len(password) != 8:
return False
password_set = set(password)
# Содержит хотя бы одну букву в верхнем регистре.
if not password_set & upper_set:
return False
# Содержит хотя бы одну букву в нижнем регистре.
if not password_set & lower_set:
return False
# Содержит хотя бы одну цифру.
if not password_set & digit_set:
return False
# Функция is_valid_password должна вернуть True,
# если переданный в качестве параметра пароль отвечает требованиям надежности.
return True
И наконец финальный код:
upper_set = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
lower_set = set('abcdefghijklmnopqrstuvwxyz')
digit_set = set('1234567890')
def is_valid_password(password):
# Длина строки пароля восемь символов.
if len(password) != 8:
return False
password_set = set(password)
# Содержит хотя бы одну букву в верхнем регистре.
# Содержит хотя бы одну букву в нижнем регистре.
# Содержит хотя бы одну цифру.
# Функция is_valid_password должна вернуть True,
# если переданный в качестве параметра пароль отвечает требованиям надежности.
return \
password_set & upper_set and \
password_set & lower_set and \
password_set & digit_set
эту проверку можно сделать еще так:
def is_valid_password(password):
b = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
c = "abcdefghijklmnopqrstuvwxyz"
d = "1234567890"
up = lw = dg = False
if len(password) >= 8:
for i in password:
if i in b: up = True
if i in c: lw = True
if i in d: dg = True
return up and lw and dg
is_valid_password('Password1') # True
Для любителей однострочных (не совсем) решений.
def valid_password(password: str):
return all((any(map(str.islower, password)),
any(map(str.isupper, password)),
any(map(str.isnumeric, password)),
len(password) == 8))
print(valid_password('`ozal.2N'))
Вывод
True