在Python 3中生成带有需求的随机字符串

时间:2015-11-18 08:15:54

标签: python random

我尝试为Active Directory生成具有以下密码要求的随机密码:至少8个字符,至少一个特殊字符,至少一个数字,至少一个小写字母和至少一个大写字母。

使用以下代码,我能够生成随机密码并检查它是否包含特殊字符。生成新密码,直到找到特殊字符。

special_char = "!@%/()=?+.-"

password_string = "".join([random.choice(string.ascii_lowercase + string.ascii_digits + string.ascii_uppercase + special_char) for n in range(8)])

while any(c in password_string for c in special_char) is not True:
    password_string = "".join([random.choice(string.ascii_lowercase + string.ascii_digits + string.ascii_uppercase + special_char) for n in range(8)])

以下问题是它只检查特殊字符并生成新密码可能会消除假设它们存在的其他要求。如何有效地实施AD密码要求?谢谢你的帮助。

5 个答案:

答案 0 :(得分:6)

您可以首先生成一个匹配的密码,首先选择一个特殊的字符和一个数字(以相同的方式选择一个低位字母和一个大写字母),填充任何内容,然后在最后调整顺序:

pwlist = ([random.choice(special_char),
           random.choice(string.ascii_digits),
           random.choice(string.ascii_lowercase),
           random.choice(string.ascii_uppercase),
          ]  
         + [random.choice(string.ascii_lowercase
                          + string.ascii_uppercase
                          + special_char
                          + string.ascii_digits) for i in range(4)])
random.shuffle(pwlist)
pw = ''.join(pwlist)

答案 1 :(得分:2)

测试while测试中的所有条件。将有效密码的测试委托给函数更容易:

special_char = "!@%/()=?+.-"
password_characters = string.ascii_letters + string.ascii_digits + special_char

def is_valid(password):
    if len(password) < 8:
        return False
    if not any(c in password for c in special_char):
        return False
    if not any(c.isdigit() for c in password):
        return False
    if not any(c.islower() for c in password):
        return False
    if not any(c.isupper() for c in password):
        return False
    return True

password_string = ''
while not is_valid(password_string):
    password_string = "".join([random.choice(password_characters)
                               for n in range(8)])

答案 2 :(得分:2)

使用集合和交集来强制执行约束......

import string
import random

special_char = "!@%/()=?+.-"
set_lower = set(string.ascii_lowercase)
set_upper = set(string.ascii_uppercase)
set_digits = set(string.digits)
set_sp = set(special_char)

all_chars = string.ascii_lowercase + \
    string.digits + \
    string.ascii_uppercase + \
    special_char

password_string = "".join([random.choice(all_chars) for n in range(8)])

def isOK(pw):
    pw = set(pw)
    for x in (set_lower, set_upper, set_digits, set_sp):
        if len(pw.intersection(x)) == 0:
            return False
    return True

while not isOK(password_string):
    password_string = "".join([random.choice(all_chars) for n in range(8)])

print password_string

答案 3 :(得分:1)

我更喜欢乌尔里希的回答。他打败了我。

import string
import random
string_specials = '!@%/()=?+.-'
string_pool = string_specials + string.ascii_letters + string.digits
pre_password = [
    random.choice(string_specials),
    random.choice(string.ascii_uppercase),
    random.choice(string.ascii_lowercase),
    random.choice(string.digits),
    random.choice(string_pool),
    random.choice(string_pool),
    random.choice(string_pool),
    random.choice(string_pool)]
scrambled = []
while pre_password:
    scrambled.append(pre_password.pop(random.randint(0, len(pre_password)-1)))
password = ''.join(scrambled)

答案 4 :(得分:0)

您可以逐一实施要求。

  • 至少8个字符
  • 至少一个特殊字符
  • 至少一位数
  • 至少一个小写和
  • 至少一个大写。

所以在你做任何其他事情之前 创建一个包含的字符串 随机选择1个特殊字符。 随机选择的1位数字符。 随机选择1个小写字符。 和随机选择的1个大写字符。 总共4个字符,其余字符可以随机选择,长度必须大于8。

所有生成的密码都无效,因此无需检查..

现在您可以抱怨密码都具有相同的可预测模式: 特殊的,数字的,小写的,大写的,随机的东西..

所以我们改变它..

import string
SpecialChars = "!@%/()=?+.-"

password = ""

import random
password += random.choice(string.ascii_uppercase)
password += random.choice(string.ascii_lowercase)
password += random.choice(string.digits)
password += random.choice(SpecialChars)

i = random.randint(4, 8)

for i in range(0,i):
    password += random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits+ SpecialChars)

password = ''.join(random.sample(password,len(password)))

print password