如何生成大小为N的字符串,由数字和大写英文字母组成,例如:

6个754z4英国U911K4型


当前回答

import string
from random import *
characters = string.ascii_letters + string.punctuation  + string.digits
password =  "".join(choice(characters) for x in range(randint(8, 16)))
print password

其他回答

有时0(零)和O(字母O)可能会令人困惑。所以我用

import uuid
uuid.uuid4().hex[:6].upper().replace('0','X').replace('O','Y')

(1) 这将为您提供所有大写和数字:

import string, random
passkey=''
for x in range(8):
    if random.choice([1,2]) == 1:
        passkey += passkey.join(random.choice(string.ascii_uppercase))
    else:
        passkey += passkey.join(random.choice(string.digits))
print passkey 

(2) 如果您以后想在密钥中包含小写字母,那么这也可以:

import string, random
passkey=''
for x in range(8):
    if random.choice([1,2]) == 1:
        passkey += passkey.join(random.choice(string.ascii_letters))
    else:
        passkey += passkey.join(random.choice(string.digits))
print passkey  

这个方法比Ignacio发布的random.choice()方法稍快,也稍令人讨厌。

它利用了伪随机算法的特性,按位和移位的存储体比为每个字符生成新的随机数更快。

# must be length 32 -- 5 bits -- the question didn't specify using the full set
# of uppercase letters ;)
_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'

def generate_with_randbits(size=32):
    def chop(x):
        while x:
            yield x & 31
            x = x >> 5
    return  ''.join(_ALPHABET[x] for x in chop(random.getrandbits(size * 5))).ljust(size, 'A')

…创建一个生成器,该生成器每次从0..31取出5位数字,直到没有剩余

…join()生成器对随机数的结果与正确的位

使用Timeit,对于32个字符串,计时为:

[('generate_with_random_choice', 28.92901611328125),
 ('generate_with_randbits', 20.0293550491333)]

…但对于64个字符串,randbits会丢失;)

除非我真的不喜欢我的同事,否则我可能永远不会在生产代码中使用这种方法。

edit:更新以适应问题(仅限大写和数字),并使用按位运算符&和>>而不是%和//

对于那些喜欢功能python的人:

from itertools import imap, starmap, islice, repeat
from functools import partial
from string import letters, digits, join
from random import choice

join_chars = partial(join, sep='')
identity = lambda o: o

def irand_seqs(symbols=join_chars((letters, digits)), length=6, join=join_chars, select=choice, breakup=islice):
    """ Generates an indefinite sequence of joined random symbols each of a specific length
    :param symbols: symbols to select,
        [defaults to string.letters + string.digits, digits 0 - 9, lower and upper case English letters.]
    :param length: the length of each sequence,
        [defaults to 6]
    :param join: method used to join selected symbol, 
        [defaults to ''.join generating a string.]
    :param select: method used to select a random element from the giving population. 
        [defaults to random.choice, which selects a single element randomly]
    :return: indefinite iterator generating random sequences of giving [:param length]
    >>> from tools import irand_seqs
    >>> strings = irand_seqs()
    >>> a = next(strings)
    >>> assert isinstance(a, (str, unicode))
    >>> assert len(a) == 6
    >>> assert next(strings) != next(strings)
    """
    return imap(join, starmap(breakup, repeat((imap(select, repeat(symbols)), None, length))))

它生成一个不定[无限]迭代器,由连接的随机序列组成,首先从给定的池中生成一个随机选择的符号的不定序列,然后将该序列分解为长度部分,然后进行连接,它应该与支持getitem的任何序列一起工作,默认情况下,它只生成一个字母数字字母的随机序列,尽管您可以轻松修改以生成其他内容:

例如生成数字的随机元组:

>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> next(irand_tuples)
(0, 5, 5, 7, 2, 8)
>>> next(irand_tuples)
(3, 2, 2, 0, 3, 1)

如果您不想使用next for generation,您可以简单地将其设置为可调用:

>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> make_rand_tuples = partial(next, irand_tuples) 
>>> make_rand_tuples()
(1, 6, 2, 8, 1, 9)

如果您想动态生成序列,只需将join设置为identity即可。

>>> irand_tuples = irand_seqs(xrange(10), join=identity)
>>> selections = next(irand_tuples)
>>> next(selections)
8
>>> list(selections)
[6, 3, 8, 2, 2]

正如其他人所提到的,如果您需要更多的安全性,请设置相应的选择功能:

>>> from random import SystemRandom
>>> rand_strs = irand_seqs(select=SystemRandom().choice)
'QsaDxQ'

默认选择器是choice,它可以为每个块多次选择相同的符号,如果相反,您希望为每个块最多选择一次相同的成员,则有一种可能的用法:

>>> from random import sample
>>> irand_samples = irand_seqs(xrange(10), length=1, join=next, select=lambda pool: sample(pool, 6))
>>> next(irand_samples)
[0, 9, 2, 3, 1, 6]

我们使用sample作为选择器,进行完整的选择,因此块的长度实际上是1,为了加入,我们只需调用next,它获取下一个完全生成的块,当然这个示例看起来有点麻烦,而且它。。。

现在可以在这里使用一个新的库(python>=3.6)

from chancepy import Chance

random_string = Chance.string(length=10, pool="someLettersAndNumbers123")