密码未创建为指定长度?

时间:2016-06-30 03:17:56

标签: python

我正在创建一个随机密码生成器,它接受用户指定的长度,但是我无法创建该函数,因为它将使密码完全符合该长度。由于我创建了4个变量,我只能将它做到4的倍数。如果我用不同的值调用函数,如10,密码不会是10长。任何建议?另外我除以4的原因是for循环不会生成4倍于leng的密码。

numbers = '1234567890'
letters = 'qwertyuiopasdfghjklzxcvbnm'
letters_caps = 'QWERTYUIOPLKJHGFDSAZXCVBNM'
symbols = '!@#$%^&*()_+=~`:"<>?|\;,."`'

def create_password(leng):
    password = ''
    lis = []
    for i in range(leng / 4):
        randnum = numbers[random.randrange(0, len(numbers))]
        lis.append(randnum)
        randletter = letters[random.randrange(0, len(letters))]
        lis.append(randletter)
        randletter_cap = letters_caps[random.randrange(0, len(letters_caps))]
        lis.append(randletter_cap)
        randsymbol = symbols[random.randrange(0, len(symbols))]
        lis.append(randsymbol)
    for items in lis:
        password += random.choice(lis)
    print password
create_password(12)

4 个答案:

答案 0 :(得分:1)

这个怎么样:

numbers = '1234567890'
letters = 'qwertyuiopasdfghjklzxcvbnm'
letters_caps = 'QWERTYUIOPLKJHGFDSAZXCVBNM'
symbols = '!@#$%^&*()_+=~`:"<>?|\;,."`'

import random

raw_psw = numbers + letters + letters_caps + symbols
raw_psw = list(raw_psw)

length = 10
for _ in range(5):
    random.shuffle(raw_psw)
    print("".join(raw_psw[:length]))
  

CVY; U&LT;,9FX

     

$ dt_2wx ^ PJ

     

9OH | KU〜2 ^克

     

KJO @ n`5H9Z

     

Y%oEXeOLv3

答案 1 :(得分:1)

如果您只关心长度并且对您的功能感到满意,最简单的解决方案是将四舍五入到下一个,然后在返回之前截断密码,例如:

def create_password(leng):
    password = ''
    for i in range((leng + 3) // 4):
        # add 4 characters however you like
        # ...
    print password[:leng] # truncate to proper length

(顺便说一句,其他人已经注意到使用''.join()构造而不是追加循环会更好,使用安全的PRNG生成密码很重要,而且你的代码可能更多如果您return密码而不是打印密码,则会灵活。)

答案 2 :(得分:1)

也许最不干扰的改变是完全循环你指定的次数,并根据模数调用不同的函数。

for i in range(leng):
    mod = i % 4
    if mod == 0:
        randitem = numbers[random.randrange(0, len(numbers))]
    elif mod == 1:
        randitem = letters[random.randrange(0, len(letters))]
    elif mod == 2:
        randitem = letters_caps[random.randrange(0, len(letters_caps))]
    else:
        randitem = symbols[random.randrange(0, len(symbols))]
    lis.append(randitem)

这显然会导致朝向循环开始的项目略微倾斜;有75%的可能性会比其他组中的符号多一个数字,一个字母符号的50%变化等等。

也许更好的方法是从所有组中随机选择并接受真正的随机性意味着您不会总是从每个组接收符号。这显然增加了攻击者的搜索空间,因为有效密码的选择受到的限制较少。

答案 3 :(得分:0)

只是为了通过时间:

class PasswordGenerator(object):
    def __init__(self, alphabet_classes, r=None):
        from random import SystemRandom
        self.__alphabet_classes = alphabet_classes
        self.__random = r if r else SystemRandom()

    def generate(self, length):
        password = []

        n_classes = len(self.__alphabet_classes)

        idx = [i for i in range(n_classes)]
        self.__random.shuffle(idx)

        for i in range(length):
            password.append(self.__random.choice(self.__alphabet_classes[idx[i % n_classes]]))
        self.__random.shuffle(password)

        return ''.join(password)


if __name__ == '__main__':
    numbers = '1234567890'
    letters = 'qwertyuiopasdfghjklzxcvbnm'
    letters_caps = 'QWERTYUIOPLKJHGFDSAZXCVBNM'
    symbols = '!@#$%^&*()_+=~`:"<>?|\;,."`'
    pg = PasswordGenerator([numbers, letters, letters_caps, symbols])
    for _ in range(5):
        print(pg.generate(1))

因此主循环从1变为n-1,其中n是给定的长度,在循环中我们首先决定使用哪个字符集,然后使用{{从{ 1}}。