几个细微之处的这个问题:
- 一些答案采用
string.printable
,但由于包含空白字符,这不是一个好主意。虽然它们对于密码来说并不严格违法,但您不能轻易看到它们,因此无法区分标签与空间(依此类推)。 下面我只用&大写字母,数字和标点符号。
- 从一组基于元件位置字符的随机选择不是随机的,因为每个的基数包括字符类不是均匀分布:小写字母; 大写字母; 数字; 标点符号。因此,生成的密码可能比标点符号和数字更多的字母;以及比数字更多的标点符号; (等等)。因此,如果使用
random.choices()
(与其他答案一样),则还应该使用weights=
和cum_weights=
选项,以消除上述偏差,方法是平稳分配。
- 也就是说,我鼓励使用Python的
secrets
模块,而不是它的random
模块用于此用例。从他们documentation on random:
警告:本模块的伪随机生成不应该用于安全目的使用 。有关安全或加密用途,请参阅 secrets模块。
下面是一个使用的Python -3功能为本溶液。它仅使用secrets.choice()
。它并不能完全解决问题随机(其他细微差别保持),但它确实改善选择分配到降低偏压:
>>> 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:使用从均匀地选择的字符生成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
最后,虽然我们这里使用的secrets
模块,类似的东西可以使用numpy
和numpy.random
完成。我希望这有帮助!
难道这只会生成长度为4的密码,因为范围(8,12)有4个元素? –