6

所以我需要生成一个 10 位密码(需要使用random模块),每次必须包含 2 个小写字母、2 个大写字母、3 个特殊符号和 3 个数字,所有这些都以随机顺序排列。我已经完成了随机密码生成器部分,但我不确定如何将其限制为 2 个小写字母、2 个大写字母、3 个特殊符号和 3 个数字。

这是我到目前为止所拥有的:

import random
import string
lc_letter = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
uc_letter = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
symbols = ["!","@","#","$","%","^","&","*","(",")","_","+","=","-","/",">","<",",",".","?","\\"]
numbers = ["0","1","2","3","4","5","6","7","8","9"]
options = [lc_letter,uc_letter,symbols,numbers]
for i in range(10):
    choice = random.choice(options)
    digit = random.choice(choice)
    print(digit, end = '')
4

6 回答 6

6

您可以使用以下常量string

import random
import string

s = ""

for i in range(2):
    s = s + random.choice(string.ascii_lowercase)
for i in range(2):
    s = s + random.choice(string.ascii_uppercase)
for i in range(3):
    s = s + random.choice(string.punctuation)
for i in range(3):
    s = s + random.choice(string.digits)

s = ''.join(random.sample(s, 10))

print(s)
于 2022-01-23T18:44:04.860 回答
3

您可以使用模块中的random.choicerandom.sample和 常量string来获取随机生成的密码。

import random
import string
lc_letter = string.ascii_lowercase
uc_letter = string.ascii_uppercase
# Could use string.punctuation here, but it would be different
# as your list doesn't contain semicolons or colons,
# while string.punctuation does.
symbols = ["!","@","#","$","%","^","&","*","(",")","_","+","=","-","/",">","<",",",".","?","\\"]
numbers = string.digits

lc_selection = [random.choice(lc_letter) for _ in range(2)]
uc_selection = [random.choice(uc_letter) for _ in range(2)]
symbol_selection = [random.choice(symbols) for _ in range(3)]
number_selection = [random.choice(numbers) for _ in range(3)]
print(''.join(random.sample(lc_selection + uc_selection + symbol_selection + number_selection, 10)))
于 2022-01-23T18:45:56.640 回答
3

首先选择每个需要的字符,然后将它们洗牌:

from random import choice as rd
from random import shuffle
import string
lc_letter = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
uc_letter = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
symbols = ["!","@","#","$","%","^","&","*","(",")","_","+","=","-","/",">","<",",",".","?","\\"]
numbers = ["0","1","2","3","4","5","6","7","8","9"]
options = [
    rd(lc_letter),
    rd(lc_letter),
    rd(uc_letter),
    rd(uc_letter),
    rd(symbols),
    rd(symbols),
    rd(symbols),
    rd(numbers),
    rd(numbers),
    rd(numbers),
]
shuffle(options)
print(''.join(options))
于 2022-01-23T18:43:38.377 回答
3

我建议的另一种方法是,从大写、小写等中取出 2 个字母,然后使用random.shuffle方法对生成的密码进行洗牌。

于 2022-01-23T18:40:03.567 回答
1

我认为 Yevgeniy Kosmak 解决方案的更好版本(独立配置更清晰,循环避免代码重复,使用choices代替choice避免循环)。

import random
import string

config = [
    (2, string.ascii_lowercase),
    (2, string.ascii_uppercase),
    (3, string.punctuation),  # or use your '!@#$%^&*()_+=-/><,.?\\'
    (3, string.digits),
]

picked = []
for k, options in config:
    picked += random.choices(options, k=k)
random.shuffle(picked)
password = ''.join(picked)

print(password)

在线尝试!

于 2022-02-01T15:43:14.203 回答
1

您实际上可以做的是制作一个长度为 10 的列表,如下所示:

dist = [0, 0, 1, 1, 2, 2, 2, 3, 3, 3]

此列表表示列表中每个索引的分布options。例如,您在选项中将小写字母放在首位,您必须选择 2 个小写值,因此分配列表中有 2 个零。

现在您可以在列表中选择一个索引:

idx = random.randint(0, len(dist))

然后,从列表中选择您的选择:options[dist[idx]]

最后是frompop的值。idxdist

dist.pop(idx)

这将以相同的概率生成所有有效密码。

于 2022-01-23T18:44:57.917 回答