简体   繁体   English

Python v3(随机密码生成器)

[英]Python v3 ( Random password generator )

My question is: how to generate a random password with a length that varies from (8 to 12 characters) each time generated.我的问题是:如何生成每次生成的长度从(8 到 12 个字符)不等的随机密码。

This is my code:这是我的代码:

import string
import random

def randompassword():
    chars=string.ascii_uppercase + string.ascii_lowercase + string.digits
    size=8 
    return ''.join(random.choice(chars) for x in range(size,12))

print(randompassword())

size = 8; range(size, 12) size = 8; range(size, 12) always returns array [8,9,10,11] , so you always get a password of length 4. Instead, determine the size of this particular password using randint ahead of time: size = 8; range(size, 12)总是返回数组[8,9,10,11] ,所以你总是得到一个长度为 4 的密码。 相反,提前使用randint确定这个特定密码的大小:

import string
import random

def randompassword():
  chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
  size = random.randint(8, 12)
  return ''.join(random.choice(chars) for x in range(size))

There are nuances to this question and certain solutions may cause password weakness problems.这个问题有细微差别,某些解决方案可能会导致password weakness问题。 Consider the following nuances along with the solution alternative.考虑以下细微差别以及解决方案替代方案。

  • Some answers employ string.printable , but this isn't a good idea since that contains whitespace characters.一些答案使用string.printable ,但这不是一个好主意,因为它包含空格字符。 While they are not strictly illegal for passwords, you cannot easily see them and therefore cannot differentiate, say, a tab from several spaces (and so on).虽然它们对于密码严格来说并不违法,但您无法轻易看到它们,因此无法区分例如一个制表符和多个空格(等等)。 Below I only employ lowercase letters & uppercase letters, digits and punctuation characters .下面我只使用小写字母和大写字母,数字和标点符号
  • Randomly choosing from a set of characters based on element-position isn't random since the cardinality of each included character-class isn't uniformly distributed: 26 Lowercase letters;根据元素位置从一组字符中随机选择不是随机的,因为每个包含的字符类的基数不是均匀分布的: 26个小写字母; 26 Uppercase letters; 26个大写字母; 10 Digits; 10位数字; 32 Punctuation characters. 32 个标点符号。 Therefore generated passwords are likely to have more letters than punctuation characters and digits;因此生成的密码的字母可能多于标点字符和数字; and more punctuation characters than digits;和比数字更多的标点符号; (and so on). (等等)。 So if random.choices() is used (as in other answers), one should also employ it's weights= and cum_weights= options, to eliminate aforementioned biases and even-out the distribution.因此,如果使用random.choices() (如在其他答案中),还应使用它的weights=cum_weights=选项,以消除上述偏差并使分布均匀。
  • That said, I encourage use of Python's secrets module rather that its random module for this use case.也就是说,我鼓励在这个用例中使用 Python 的secrets模块而不是它的random模块。 From their documentation on random :从他们关于 random文档中

Warning: The pseudo-random generators of this module should not be used for security purposes.警告:该模块的伪随机生成器不应用于安全目的。 For security or cryptographic uses, see the secrets module.对于安全或加密用途,请参阅secrets模块。

Here is one functionally-oriented solution using Python-3 .这是一个使用Python-3的面向功能的解决方案。 It uses secrets.choice() only.它仅使用secrets.choice() It doesn't totally solve the random problem (other nuances remain), but it does improve selection-distribution to reduces bias:它并没有完全解决随机问题(其他细微差别仍然存在),但它确实改善了选择分布以减少偏差:

>>> import string, secrets

>>> char_classes = (string.ascii_lowercase,
                    string.ascii_uppercase,
                    string.digits,
                    string.punctuation)

>>> size = lambda: secrets.choice(range(8,13))                  # Chooses a password length.
>>> char = lambda: secrets.choice(secrets.choice(char_classes)) # Chooses one character, uniformly selected from each of the included character classes.
>>> pw   = lambda: ''.join([char() for _ in range(size())])     # Generates the variable-length password.

DEMO : Generate 10 variable-length password-strings using characters uniformly selected from each of our character classes:演示:使用从我们的每个字符类中统一选择的字符生成 10 个可变长度的密码字符串:

>>> for i in range(1,11):
>>>    p = pw()
>>>    print('%i) %i chars :: %s' % (i,len(p),p))
 1) 11 chars :: IwWNEAUmnJt
 2) 10 chars :: ;N/'tO6RTv
 3)  8 chars :: l=5.2CDh
 4) 10 chars :: V0=I+A`t2Q
 5) 12 chars :: PQm8:f,#56"9
 6) 10 chars :: KOdx9~%r;F
 7) 11 chars :: <?67U8}3>F{
 8) 11 chars :: G$5y~3fE7o*
 9) 10 chars :: 70,|=Rexwn
10)  8 chars :: &31P^@cU

Finally, while we used the secrets module here, something similar could be done using numpy and numpy.random .最后,虽然我们在这里使用了secrets模块,但可以使用numpynumpy.random完成类似的事情。 I hope this helps!我希望这会有所帮助!

Edit: As stated below the string.printable string contains characters that can cause issues when used for passwords.编辑:如下所述, string.printable字符串包含在用于密码时可能导致问题的字符。 Instead of relying on this build-in set you're probably better off defining a custom set of usable characters.与其依赖这个内置集,不如定义一组自定义的可用字符。 Don't forget about characters as space which are LHF to improving the strength of a password.不要忘记字符作为空格,它们是提高密码强度的 LHF。 Just be sure to handle heading/tailing spaces as the UI could potentially strip the input of a user preventing them from entering a valid password.请务必处理标题/尾随空格,因为 UI 可能会剥离用户的输入,从而阻止他们输入有效密码。

 
 
 
  
  import random import string def randompassword(): return ''.join([random.choice(string.printable) for _ in range(random.randint(8, 12))])
 
 

I believe it's only printing 4 characters due to size = 8 and range(size,12) .我相信由于size = 8range(size,12)它只打印 4 个字符。 This translates to range(8, 12) = 4 characters.这转化为 range(8, 12) = 4 个字符。 You could increase the second number to allocate for a larger range to print random characters for like so您可以增加第二个数字以分配更大的范围来打印随机字符,就像这样

import string
import random

def randompassword():
    chars=string.ascii_uppercase + string.ascii_lowercase + string.digits
    size= 8
    return ''.join(random.choice(chars) for x in range(size,20))

print(randompassword())

Also be sure to check out python's random documentation here .还请务必在此处查看 python 的随机文档。

string.ascii_letters #considers all the small case and large case alphabets. string.ascii_letters #考虑所有小写字母和大写字母。 string.digits #considers 0 to 9 digits. string.digits #考虑 0 到 9 位数字。 string.punctuation #considers the special characters like symbols. string.punctuation #考虑特殊字符,如符号。 random.choice #considers to randomly pick from the given data. random.choice #考虑从给定数据中随机选择。 range(random.randint(6, 12)) #considers to pick a random int range from the given data. range(random.randint(6, 12)) #考虑从给定数据中选择一个随机整数范围。 print(generator_pw()) #prints random generated password. print(generator_pw()) #打印随机生成的密码。

import random, string

def generator_pw():
    pwd = string.ascii_letters + string.digits + string.punctuation
    return "".join(random.choice(pwd) for x in range(random.randint(6, 12)))

print(generator_pw())

range(size,12) only returns numbers between size (which you've hardcoded to 8) and 12, so your passwords will only be 4 characters long. range(size,12)仅返回size (您已硬编码为 8)和 12 之间的数字,因此您的密码只有 4 个字符长。 Make that ... for x in range(size) .使... for x in range(size)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM