#python #passwords
#питон #пароли
Вопрос:
Я должен создать программу для проверки подлинности пароля. Условия следующие: не менее 8 символов, 1 заглавная буква, 1 строчная буква, 1 число в диапазоне 0-9, 1 символ. Если выполнено 3/4 из условий (исключая длину пароля, поскольку он всегда должен быть длиннее 8 символов), программа должна проверить надежность пароля. Если длина пароля составляет 8 символов, то его сила равна 1. на каждые 4 дополнительных символа сила увеличивается на 1. В случае соблюдения всех условий прочность должна быть удвоена.
В приведенном ниже коде я написал огромную строку кода, но я думаю, что допустил ошибку и что есть гораздо более быстрый способ сделать это. Поэтому я спрашиваю вас, есть ли способ сделать это быстрее или нет. Если да, то что бы это было?
def is_valid_password(): pwd=input("Enter a password: ") f=1 l=0 u=0 d=0 s=0 p=0 if(len(pwd)gt;=8): for i in pwd: if i.islower(): l =1 if i.isupper(): u =1 if i.isdigit(): d =1 if(i=='!' or i=='@' or i=='#' or i=='
Ответ №1:
Я бы, наверное, составил список функций , таких как testLength()
, testUpper()
, testDigit()
, и так далее. Функции просто возвращают 1 (выполнено) или 0 (не выполнено). Обратите внимание, что действительно легко расширить количество и вид тестов.
Теперь вы пишете что-то вроде
numPassed = testLength(pwd) testUpper(pwd) testDigit(pwd) ... if (numPassed lt; (3 * numTests)/4) issueError("password too weak")
Это своего рода псевдокод, но я думаю, что идея понятна. Обратите внимание, что этот код, конечно, не быстрее, но его легко понять и легко поддерживать или расширять. (Это тоже не медленно, если вы не хотите проверять миллиард паролей одновременно).
Комментарии:
1. Спасибо, что ответили. В данном конкретном случае мне все равно, быстрая программа или нет, поэтому я попробую.
2. В этой строке "если (числится
3. @DnsStratos Я не определил
numPassed
в своем отрывке кода, но он должен содержать то, что в нем написано: общее количество тестов, которые вы собираетесь выполнить. В вашем случае это было бы 4, если я правильно посчитал4. О, о, я понимаю. Еще раз спасибо
Ответ №2:
Вы могли бы попробовать этот способ, используя регулярное выражение. укажите, что вам нужно найти в скобках и в или в шаблоне:
passwd='P%amp;ippo8lo' pattern=r'(d)|([[:upper:]])|([[:lower:]])|([$%amp;])'
1-цифра, 2-заглавная буква, 3-строчная буква, 4-символ
метод 'findall' вернет список наборов, в которых вам просто нужно убедиться, что все поля были использованы:
rt=regex.findall(pattern, passwd) [ ('', 'P', '', '') ('', '', '', '%') ('', '', '', 'amp;') ('', '', 'i', '') ('', '', 'p', '') ('', '', 'p', '') ('', '', 'o', '') ('8', '', '', '') ('', '', 'l', '') ('', '', 'o', '') ]
теперь твердость пароля зависит от того, сколько полей набора было использовано:
good = [False] * 4 for s in rt: for i in range(0, len(s)): if s[i] != '': good[i] = True print(good) [True, True, True, True]
если один из запросов не был использован, соответствующее поле будет иметь значение False
О длине пароля:
ovr_len = len(password) - 8 hardness_point = int(ovr_len / 4) total_point = hardness_point
одно очко каждые 4 символа после 8
Ответ №3:
Лично я делаю это:
import re from math import ceil def is_valid_password(PassWord): Conditions = 0 if len(PassWord) lt; 8: print(f"The password ({PassWord}) is too short !") return 0 # Or re.findall("[a-z]", PassWord): if PassWord != PassWord.lower(): Conditions = 1 # Or re.findall("[A-Z]", PassWord): if PassWord != PassWord.upper(): Conditions = 1 if re.findall("[0-9]", PassWord): Conditions = 1 # Or re.findall("[!@#$amp;_]", PassWord): if re.findall("[^a-zA-Z0-9]", PassWord): Conditions = 1 if Conditions lt; 3: print(f"The password ({PassWord}) not respect the conditions !") return 0 # Or Power = 1 ceil((len(PassWord) - 8) / 4) # if you want : # 8 char = 1 # 9-12 char = 2 # 13-16 char = 3 Power = 1 int((len(PassWord) - 8) / 4) if Conditions == 4: Power *= 2 print(f"Valid password ({PassWord}) with strength {Power}") return 1 is_valid_password("Hello") # Error is_valid_password("hello2020") # Error is_valid_password("HELLO2020") # Error is_valid_password("Hello2022") # 1 is_valid_password("Hello 2022") # 2 is_valid_password("HelloHello2022") # 2 is_valid_password("Hello _ 2022") # 4 is_valid_password("Hello Hello 2022") # 6
Я думаю, это проще и удобочитаемее.
Комментарии:
1. это так, но есть одна проблема, связанная с силой. Если длина находится между значениями 9-11, она не увеличится на 1. так, например, сила T$st12345 будет равна 2 вместо 4. Надеюсь, я хорошо это объяснил
2.Когда вы говорите "длина 8 символов равна 1. на каждые 4 дополнительных символа сила увеличивается на 1", я понимаю: - 8-11 = 1 # Больше нет 4 символов... - 12-15 = 2 # Есть еще 4 символа... - Если вы хотите 2 на 9 символов: -
from math import ceil
Power = 1 ceil((len(PassWord) - 8) / 4)
or i=='amp;' or i=='_'): s =1 if((l u d s)==len(pwd) and l==0 and ugt;=1 and dgt;=1 and sgt;=1) or ((l u d s)==len(pwd) and lgt;=1 and u==0 and dgt;=1 and sgt;=1) or ((l u d s)==len(pwd) and lgt;=1 and ugt;=1 and d==0 and sgt;=1) or ((l u d s)==len(pwd) and lgt;=1 and ugt;=1 and dgt;=1 and s==0) or ((l u d s)==len(pwd) and lgt;=1 and ugt;=1 and dgt;=1 and sgt;=1): if((l u d s)==len(pwd) and lgt;=1 and ugt;=1 and dgt;=1 and sgt;=1): if(len(pwd)gt;12): f=(f (len(pwd)-8)//4)*2 elif(len(pwd)gt;=9 and len(pwd)lt;=12): f==4 elif(len(pwd)==8): f==2 print(f"Valid password with strength {f}") else: if(len(pwd)gt;12): f=f (len(pwd)-8)//4 elif(len(pwd)gt;=9 and len(pwd)lt;=12): f==2 elif(len(pwd)==8): f==1 print(f"Valid password with strength {f}") else: print("Invalid password!") while True: is_valid_password()
Ответ №1:
Я бы, наверное, составил список функций , таких как testLength()
, testUpper()
, testDigit()
, и так далее. Функции просто возвращают 1 (выполнено) или 0 (не выполнено). Обратите внимание, что действительно легко расширить количество и вид тестов.
Теперь вы пишете что-то вроде
Это своего рода псевдокод, но я думаю, что идея понятна. Обратите внимание, что этот код, конечно, не быстрее, но его легко понять и легко поддерживать или расширять. (Это тоже не медленно, если вы не хотите проверять миллиард паролей одновременно).
Комментарии:
1. Спасибо, что ответили. В данном конкретном случае мне все равно, быстрая программа или нет, поэтому я попробую.
2. В этой строке «если (числится
3. @DnsStratos Я не определил
numPassed
в своем отрывке кода, но он должен содержать то, что в нем написано: общее количество тестов, которые вы собираетесь выполнить. В вашем случае это было бы 4, если я правильно посчитал4. О, о, я понимаю. Еще раз спасибо
Ответ №2:
Вы могли бы попробовать этот способ, используя регулярное выражение. укажите, что вам нужно найти в скобках и в или в шаблоне:
1-цифра, 2-заглавная буква, 3-строчная буква, 4-символ
метод ‘findall’ вернет список наборов, в которых вам просто нужно убедиться, что все поля были использованы:
теперь твердость пароля зависит от того, сколько полей набора было использовано:
если один из запросов не был использован, соответствующее поле будет иметь значение False
О длине пароля:
одно очко каждые 4 символа после 8
Ответ №3:
Лично я делаю это:
Я думаю, это проще и удобочитаемее.
Комментарии:
1. это так, но есть одна проблема, связанная с силой. Если длина находится между значениями 9-11, она не увеличится на 1. так, например, сила T$st12345 будет равна 2 вместо 4. Надеюсь, я хорошо это объяснил
2.Когда вы говорите «длина 8 символов равна 1. на каждые 4 дополнительных символа сила увеличивается на 1», я понимаю: — 8-11 = 1 # Больше нет 4 символов… — 12-15 = 2 # Есть еще 4 символа… — Если вы хотите 2 на 9 символов: —
from math import ceil
Power = 1 ceil((len(PassWord) - 8) / 4)