У меня есть вопросы о том, как понять, почему мой генератор паролей не работает должным образом - PullRequest
0 голосов
/ 09 мая 2020

Я начинающий программист, поэтому, пожалуйста, простите меня, если я не замечаю очевидного.

У меня возникли проблемы с генератором паролей. Во-первых, код не выполняется должным образом, когда я запускаю сценарий, он печатает «Ваш пароль:» и ничего больше, пароль не сгенерируется.

Я проверил код с точками останова, и ничего не кажется необычным. Мне просто нужна помощь, чтобы решить, почему он не генерируется.

Еще раз, пожалуйста, простите меня, если я не замечаю «очевидного».

Спасибо! И мой код показан ниже:

import random

Characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
Special_Characters = "~!@#$%^&*()_"
Numbers = "1234567890"
Chosen_Characters = []
Chosen_Special_Characters = []
Chosen_Numbers = []
Password = ""
Nums_amt = 0
S_Character_amt = 0
Character_amt = 0
Total_characters = Nums_amt + S_Character_amt + Character_amt

def Amount_of_Characters():
    num = random.randint(1, 9)
    return(num)

def Character_chooser(A_o_C, Char_amt, Char):
    global Chosen_Characters
    for i in range(A_o_C):
        Chosen_Characters += [random.choice(Char)]
        Char_amt += 1
    return(Chosen_Characters)

def Special_Character_chooser(A_o_C, S_Char_amt, S_Char):
    global Chosen_Special_Characters
    for i in range(A_o_C):
        Chosen_Special_Characters += [random.choice(S_Char)]
        S_Char_amt += 1
    return(Chosen_Special_Characters)

def Number_chooser(A_o_C, Num_amt, Num):
    global Chosen_Numbers
    for i in range(A_o_C):
        Chosen_Numbers += [random.choice(Num)]
        Num_amt += 1
    return(Chosen_Numbers)

def Assembler(A_o_C, C_c, S_C_c, N_c, Total_char, S_Char_amt, Char_amt, Num_amt, Pword):    
    one = random.shuffle(C_c)
    two = random.shuffle(S_C_c)
    three = random.shuffle(N_c)
    for i in range(Total_char):
        chooser = random.randint(1, 3)
        if i + 1 <= Char_amt:
            if chooser == 1:
                temp_num = random.randint(0, len(one))
                Pword += one[temp_num]
                two.pop(temp_num)
        if i + 1 <= S_Char_amt + Char_amt and i + 1 > Char_amt:
            if chooser == 1:
                temp_num = random.randint(0, len(two))
                Pword += two[temp_num]
                two.pop(temp_num)
        if i + 1 > S_Char_amt + Char_amt:
            if chooser == 1:
                temp_num = random.randint(0, len(three))
                Pword += three[temp_num]
                two.pop(temp_num)
    return(Pword)

A = Amount_of_Characters()
B = Character_chooser(Amount_of_Characters(), Character_amt, Characters)
C = Special_Character_chooser(Amount_of_Characters(), S_Character_amt, Special_Characters)
D = Number_chooser(Amount_of_Characters(), Nums_amt, Numbers)

print("Your password is: " + Assembler(A, B, C, D, Total_characters, S_Character_amt, Character_amt, Nums_amt, Password))

Ответы [ 2 ]

2 голосов
/ 09 мая 2020

TL; DR: ваш код предполагает, что если вы передадите переменную в функцию и измените значение параметра, он изменит оригинал. Это не так. Эта и некоторые другие ошибки приводят к сбою программы.

Хороший стиль программирования - это не только вопрос хорошего внешнего вида, но и упрощение чтения вашего кода для других программистов, а также для вас в будущем. Поэтому позвольте мне прокомментировать несколько проблем с вашим кодом:

  • Вы назвали функцию Amount_of_Characters, но вы не должны использовать заглавные буквы в именах функций в Python, поскольку они обозначают классы вместо этого назовите его amount_of_characters
  • Затем вы назначаете функцию результату A, который на самом деле ничего не делает, но имя переменной также должно быть в нижнем регистре, назовите его a
  • Сделав это для четырех отдельных функций, вы передаете их все в другую функцию (опять же, заглавные буквы, но вы их понимаете), у которой есть параметры с именами типа A_o_C, что совершенно неинформативно и очень сложно отслеживать. при смешивании с C_c, S_C_c, и т.д. c.

Не делайте свой код загадочным и трудным для чтения - он никому не нравится, и никто не будет вас в будущем.

Посмотрев на ваш код, может показаться, что Amount_of_Characters просто возвращает случайное целое число от 1 до 9, Character_chooser генерирует список из n случайных символов из некоторой строки, Special_Character_chooser делает то же самое (за исключением того, что они оба изменяют другой глобальный). И Number_chooser делает то же самое снова.

Функции, которые имеют глобальные побочные эффекты, почти всегда являются ошибкой дизайна. Вместо того, чтобы манипулировать глобальной переменной, просто верните то, что должна произвести функция.

Ваш Assembler наконец переходит к перемешиванию порядка случайно выбранных последовательностей - но поскольку они уже были случайными, это бессмысленно. Кажется, можно ожидать, что переменные, подобные Char_amt, были изменены предыдущими функциями, но на самом деле они не объявлены как global, поэтому у них нет правильных значений. Если они это сделали, Assembler, кажется, случайным образом выбирает количество символов из перемешанных случайных строк.

Итак, в конце концов, все, что ваш скрипт делает, это:

  • генерировать строка длиной n
  • каждый символ строки случайным образом выбирается из одного из трех наборов символов (английские sh буквы, числа и некоторые специальные символы) с равными шансами

Следовательно, этот сценарий делает то же самое (как только вы заставите свой работать):

import random
from string import ascii_letters, digits


def generate_pass(n):
    chars = ['~!@#$%^&*()_', ascii_letters, digits]
    return ''.join([
        random.choice(chars[random.randint(0, 2)]) for _ in range(n)
    ])


print(generate_pass(10))

Все остальное в вашем скрипте просто перемещает вещи и присваивает им имена. И многократное применение случайных функций к чему-либо не обязательно делает его более случайным. Если вы думаете, что случайная библиотека в Python почему-то недостаточно случайна, вы можете найти лучшие библиотеки, но для целей генерации паролей это было бы бессмысленно.

И между прочим: это предполагает на самом деле вы хотите, чтобы в вашем пароле было примерно равное количество цифр, букв и специальных символов, иначе он мог бы быть еще короче:

import random
from string import ascii_letters, digits


def generate_pass(n):
    chars = '~!@#$%^&*()_' + ascii_letters + digits
    return ''.join([random.choice(chars) for _ in range(n)])


print(generate_pass(10))
0 голосов
/ 09 мая 2020

Ваша ошибка заключается в основном в Ассемблере

Ошибка 1: Total_char, S_Character_amt, Character_amt, Nums_amt

Запустите это:

def Assembler(A_o_C, C_c, S_C_c, N_c, Total_char, S_Char_amt, Char_amt, Num_amt, Pword):    
one = random.shuffle(C_c)
two = random.shuffle(S_C_c)
three = random.shuffle(N_c)
print(Total_char)
for i in range(Total_char):
    chooser = random.randint(1, 3)
    if i + 1 <= Char_amt:
        if chooser == 1:
            temp_num = random.randint(0, len(Numbers)-1)
            Pword += Numbers[temp_num]
            two.pop(temp_num)
            print("A")
    if i + 1 <= S_Char_amt + Char_amt and i + 1 > Char_amt:
        if chooser == 1:
            temp_num = random.randint(0, len(Special_Characters))
            Pword += Special_Characters[temp_num]
            two.pop(temp_num)
            print("B")
    if i + 1 > S_Char_amt + Char_amt:
        if chooser == 1:
            temp_num = random.randint(0, len(three))
            Pword += three[temp_num]
            two.pop(temp_num)
            print("C")
print(Pword)
return(Pword)

Вы заметите, что ваш Total_Char всегда равен 0, поэтому for l oop никогда не выполнялся. Это потому, что ваши Total_characters изначально были определены как 0

Nums_amt = 0
S_Character_amt = 0
Character_amt = 0
Total_characters = Nums_amt + S_Character_amt + Character_amt # 0+0+0

После чего выведите все ваши другие amts:

print(Total_characters) #0
print(S_Character_amt)  #0
print(Character_amt)    #0
print(Nums_amt)         #0

Итак, по сути, пример запуска того, что ваши действия были

Assembler (6, ['l', 'Z', 'w', 'e', ​​'O', 'K', 't'], ['#', ' % ',' # ',' (',' * ',' $ ',' ^ ',') '], [' 3 ',' 2 ',' 3 ',' 8 '], 0, 0, 0, 0, "")

Ошибка 2: Shuffle

random.shuffle () перемешивает элемент списка на месте и возвращает None, таким образом, один, два и три - все Нет Типы

random.shuffle (C_ c) сам по себе достаточно, и вы можете заменить все в ассемблере обратно на C_ c. Аналогичным образом для двух и трех

Ошибка 3: L oop условие

Какое отношение ваш индекс l oop имеет к длине массива символов ? Вам, вероятно, следует смотреть только на длину ваших массивов. Если в списке уже ничего нет, пропустите.

...