0

我是一个初学者程序员,所以如果我没有注意到显而易见的事情,请原谅我。

我的密码生成器遇到了问题。首先,当我运行脚本时代码没有正确执行,它打印“你的密码是:”,没有别的,密码不会生成。

我用断点检查了代码,似乎没有什么异常。我只是需要帮助来解决为什么它不会生成。

再次,如果我没有注意到“明显”,请原谅我。

谢谢!我的代码如下所示:

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))
4

2 回答 2

2

TL; DR:您的代码假定如果您将变量传递给函数并更改参数的值,它会更改原始值。它没有。该错误和其他一些错误会导致程序失败。

良好的编程风格不仅仅是看起来好看,而是让您的代码更容易被其他程序员以及未来的自己阅读。因此,请允许我对您的代码的一些问题发表评论:

  • 你命名了一个函数Amount_of_Characters,但你不应该在 Python 中的函数名中使用大写字母,因为它们表示类,而是命名它amount_of_characters
  • 然后将函数分配给 result A,它实际上并没有做任何事情,但变量名也应该是小写的,命名它a
  • 在对四个单独的函数执行此操作后,将它们全部传递给另一个函数(同样,大写字母,但你明白了),该函数具有名为 like 的参数A_o_C,这完全是非描述性的,并且在混合时很难跟踪C_c,S_C_c等。

不要让你的代码看起来晦涩难懂——没有人喜欢它,你也不会喜欢它。

查看您的代码后,似乎Amount_of_Characters只返回一个介于 1 和 9 之间的随机整数,Character_chooser从某个字符串生成 n 个随机字符的列表,Special_Character_chooser执行完全相同的操作(除了它们都修改了另一个全局)。并Number_chooser再次这样做。

具有全局副作用的函数几乎总是设计错误。无需操作全局变量,只需返回函数应该产生的内容。

Assembler最终会继续打乱随机选择的序列的顺序 - 但由于它们已经是随机的,因此毫无意义。似乎期望变量 likeChar_amt已被先前的函数修改,但实际上它们并未声明为global,因此它们没有正确的值。如果他们这样做了,Assembler似乎会从打乱的随机字符串中随机选择一些字符。

所以,最后,你的脚本所做的就是:

  • 生成长度为 n 的字符串
  • 字符串的每个字符都是从三个字符集合(英文字母、数字和一些特殊字符)中以相同的几率随机选择的

因此,这个脚本做同样的事情(一旦你开始工作):

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))
于 2020-05-09T04:25:52.160 回答
0

您的错误主要在于汇编程序

错误 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 循环。这是因为您的 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

所以本质上你正在做的一个例子是

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

错误 2:随机播放

random.shuffle() 将列表项打乱并返回 None 因此一、二和三都是 None 类型

random.shuffle(C_c) 本身就足够了,您可以用 C_c 替换汇编程序中的所有内容。同样对于两个和三个

错误 3:循环条件

您的循环索引与字符数组的长度有什么关系?您可能应该只查看数组的长度。如果列表中已经没有任何内容,请跳过。

于 2020-05-09T04:41:17.287 回答