我对如何理解为什么我的密码生成器无法正常执行有疑问
I have questions on how to understand why my password generator is not executing properly
我是一名初级程序员,所以如果我没有注意到显而易见的地方,请原谅我。
我 运行 我的密码生成器有问题。首先,当我 运行 脚本时代码没有正确执行,它打印 "Your password is: ",没有别的,密码不会生成。
我已经检查了带有断点的代码,似乎没有任何异常。我只是需要帮助来解决它无法生成的原因。
再一次,如果我没有注意到'obvious',请原谅我。
谢谢!我的代码如下所示:
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))
TL;DR:您的代码假设如果您将变量传递给函数并更改参数值,它会更改原始值。它没有。这个错误和其他一些错误导致程序失败。
良好的编程风格不仅仅是好看的问题,还在于让其他程序员以及未来的自己更容易阅读您的代码。所以请允许我对您的代码的一些问题发表评论:
- 您将一个函数命名为
Amount_of_Characters
,但您不应在 Python 中的函数名称中使用大写字母,因为它们表示 类,而是将其命名为 amount_of_characters
- 然后将函数赋值给result
A
,这实际上并没有做任何事情,但是变量名也应该是小写的,将其命名为a
- 在对四个单独的函数执行此操作后,您将它们全部传递给另一个函数(同样,大写字母,但你明白了),该函数的参数命名为
A_o_C
,完全没有描述性,并且当与 C_c
、S_C_c
等混合时很难跟踪
不要让您的代码看起来晦涩难懂 - 没有人喜欢它,您将来也不会喜欢它。
查看您的代码后,Amount_of_Characters
似乎只是 return 一个介于 1 和 9 之间的随机整数,Character_chooser
从某个字符串生成一个包含 n 个随机字符的列表, Special_Character_chooser
做了完全相同的事情(除了它们都修改了另一个全局)。 Number_chooser
再次做同样的事情。
具有全局副作用的函数几乎总是设计错误。不是操纵全局变量,只是 return 函数应该产生什么。
您的 Assembler
最终开始打乱随机选择序列的顺序 - 但由于它们已经是随机的,所以这毫无意义。似乎期望像Char_amt
这样的变量已经被前面的函数修改了,但实际上它们并没有被声明为global
,所以它们没有正确的值。如果他们这样做了,Assembler
似乎 select 从随机字符串中随机选择了一些字符。
所以,最后,您的脚本所做的是:
- 生成长度为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))
你的错误主要在汇编
错误 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
然后打印你所有的其他金额:
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() 随机播放列表项 returns None 因此一、二和三都是 None 类型
random.shuffle(C_c) 本身就足够了,您可以将汇编程序中的所有内容替换为 C_c 。同样对于两个和三个
错误 3:循环条件
循环索引与字符数组的长度有什么关系?您可能应该只查看数组的长度。如果列表中已经没有任何内容,请跳过。
我是一名初级程序员,所以如果我没有注意到显而易见的地方,请原谅我。
我 运行 我的密码生成器有问题。首先,当我 运行 脚本时代码没有正确执行,它打印 "Your password is: ",没有别的,密码不会生成。
我已经检查了带有断点的代码,似乎没有任何异常。我只是需要帮助来解决它无法生成的原因。
再一次,如果我没有注意到'obvious',请原谅我。
谢谢!我的代码如下所示:
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))
TL;DR:您的代码假设如果您将变量传递给函数并更改参数值,它会更改原始值。它没有。这个错误和其他一些错误导致程序失败。
良好的编程风格不仅仅是好看的问题,还在于让其他程序员以及未来的自己更容易阅读您的代码。所以请允许我对您的代码的一些问题发表评论:
- 您将一个函数命名为
Amount_of_Characters
,但您不应在 Python 中的函数名称中使用大写字母,因为它们表示 类,而是将其命名为amount_of_characters
- 然后将函数赋值给result
A
,这实际上并没有做任何事情,但是变量名也应该是小写的,将其命名为a
- 在对四个单独的函数执行此操作后,您将它们全部传递给另一个函数(同样,大写字母,但你明白了),该函数的参数命名为
A_o_C
,完全没有描述性,并且当与C_c
、S_C_c
等混合时很难跟踪
不要让您的代码看起来晦涩难懂 - 没有人喜欢它,您将来也不会喜欢它。
查看您的代码后,Amount_of_Characters
似乎只是 return 一个介于 1 和 9 之间的随机整数,Character_chooser
从某个字符串生成一个包含 n 个随机字符的列表, Special_Character_chooser
做了完全相同的事情(除了它们都修改了另一个全局)。 Number_chooser
再次做同样的事情。
具有全局副作用的函数几乎总是设计错误。不是操纵全局变量,只是 return 函数应该产生什么。
您的 Assembler
最终开始打乱随机选择序列的顺序 - 但由于它们已经是随机的,所以这毫无意义。似乎期望像Char_amt
这样的变量已经被前面的函数修改了,但实际上它们并没有被声明为global
,所以它们没有正确的值。如果他们这样做了,Assembler
似乎 select 从随机字符串中随机选择了一些字符。
所以,最后,您的脚本所做的是:
- 生成长度为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))
你的错误主要在汇编
错误 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
然后打印你所有的其他金额:
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() 随机播放列表项 returns None 因此一、二和三都是 None 类型
random.shuffle(C_c) 本身就足够了,您可以将汇编程序中的所有内容替换为 C_c 。同样对于两个和三个
错误 3:循环条件
循环索引与字符数组的长度有什么关系?您可能应该只查看数组的长度。如果列表中已经没有任何内容,请跳过。