0
# Create a function to generate a random, 8-character password.
# It should satisfy the following requirements:

# 1) There should be exactly two characters from each of the following categories:
# - Uppercase letters
# - Lowercase letters
# - Numerals 0 - 9
# - Special Characters from the string “!@#$%^&*”

# 2) No two character categories should be adjacent.
# bad example: AXyu74$^

# 3) The categories should be randomly ordered.
# good example: 8b&U6Nz!  NLSUNULS
# */
import random, string
def generate_password():
    store = {}
    for category in 'ULSN':
        store[category] = []
    for i in range(2):
        store['U'].append(random.choice(string.ascii_letters).upper())
        store['L'].append(random.choice(string.ascii_letters).lower())
        store['N'].append(str(random.randint(0,9)))
        store['S'].append("!@#$%^&*"[random.randrange(0,7) + 1])
    print("".join([item for sublist in store.values() for item in sublist]))
    for item in store.items():
        print(item)
     # shuffle and eliminate adjacency
generate_password()

有一个有四个键的字典。每个键映射到不同的类别,每个键都有一个包含 2 个字符的列表作为值。

你如何打乱字典以随机顺序构建一个字符串,这样没有键是相邻的?

目标是有效地返回一个没有相邻值的 8 个字符长的字符串。

示例和测试用例在问题陈述中

4

2 回答 2

0

在解决了这个问题之后,我认为解决方案是将其分解为两部分:模式和映射。

每个有效模式都从两个不同的类别开始;暂时称他们为A和B。这将 AB****** 作为起始部分模式。在某个时候,将使用第三类 C:

ABC*****
ABAC****
ABABC***

By completing these part-patterns you can generate a list of all valid patterns from ABCDABCD to ABABCDCD. These patterns can either be hard coded into the program or loaded from an auxiliary text file. By my rough calculation there are less than 6! = 720 valid patterns, though I'm not sure how many less.

Having picked a random pattern, you need a mapping from ABCD to ULNS. A random shuffle of ULNS should be enough. Read through the chosen pattern and use the mapping to determine which categories to pick from and in what order.

For example, pattern ABCADCBD with mapping LSUN gives LSULNUSN. Breaking the problem into separate parts, pattern and mapping, makes it easier to deal with.

于 2021-04-10T08:05:06.010 回答
0

my answer

import string
import random

categories = "ULNS"
prev = curr = None
passwd = ""
used = {}
for category in categories:
    used[category] = 0

while len(passwd) != 8: 
    while prev == curr:
        curr = random.choice(categories)

    if curr == "U":
        passwd += random.choice(list(string.ascii_uppercase))
    if curr == "L":
        passwd += random.choice(list(string.ascii_lowercase))
    if curr == "N":
        passwd += random.choice([str(i) for i in range(10)])
    if curr == "S":
        passwd += random.choice([s for s in "!@#$%^&*"])
    
    used[curr] += 1
    if used[curr] == 2: 
        used.pop(curr)
        categories = "".join(list(used.keys()))
    prev = curr
        
print(passwd)
于 2021-04-22T20:51:10.823 回答