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

6个754z4英国U911K4型


当前回答

生成包含字母、数字、“_”和“-”的随机16字节ID

os.urantom(16).translate((f'{string.ascii_letters}{string.digitals}-'*4).encode('ascii'))

其他回答

我在寻找不同的答案,并花时间阅读了秘密文件

机密模块用于生成适合于管理数据(如密码、帐户验证、安全令牌和相关机密)的加密强随机数。特别是,应优先使用秘密,而不是随机模块中的默认伪随机数生成器,其设计用于建模和模拟,而不是安全或密码学。

深入了解它所提供的功能,我发现如果你想模仿像Google Drive ID这样的ID,我会发现一个非常方便的功能:

secrets.token_urlsafe([nbytes=无])返回随机URL安全文本字符串,包含n字节随机字节。文本是Base64编码的,因此平均每个字节大约有1.3个字符。如果nbytes为None或未提供,则使用合理的默认值。

使用方法如下:

import secrets
import math

def id_generator():
    id = secrets.token_urlsafe(math.floor(32 / 1.3))
    return id

print(id_generator())

输出32个字符的长度id:

joXR8dYbBDAHpVs5ci6iD-oIgPhkeQFk

我知道这与OP的问题稍有不同,但我希望这对许多正在寻找与我相同用例的人仍然有帮助。

我会这样做:

import random
from string import digits, ascii_uppercase

legals = digits + ascii_uppercase

def rand_string(length, char_set=legals):

    output = ''
    for _ in range(length): output += random.choice(char_set)
    return output

或者只是:

def rand_string(length, char_set=legals):

    return ''.join( random.choice(char_set) for _ in range(length) )
>>> import random
>>> str = []
>>> chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
>>> num = int(raw_input('How long do you want the string to be?  '))
How long do you want the string to be?  10
>>> for k in range(1, num+1):
...    str.append(random.choice(chars))
...
>>> str = "".join(str)
>>> str
'tm2JUQ04CK'

random.choice函数在列表中选择一个随机条目。还可以创建一个列表,以便可以在for语句中追加字符。在结尾str是[t','m','2','J','U','Q','0','4','C','K'],但是str=“”.join(str)会处理这一点,留下'tm2JUQ04CK'。

希望这有帮助!

对于那些喜欢功能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,它获取下一个完全生成的块,当然这个示例看起来有点麻烦,而且它。。。

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