使用大写字母和数字的随机字符串生成

2022-09-05 00:52:42

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

  • 6U1S75
  • 4Z4韩国
  • U911K4

答案 1

用一行回答:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

或者更短的从Python 3.6开始使用random.choices()

''.join(random.choices(string.ascii_uppercase + string.digits, k=N))

加密更安全的版本:请参阅此帖子

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))

详细介绍,具有干净功能以供进一步重用:

>>> import string
>>> import random
>>> def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
...    return ''.join(random.choice(chars) for _ in range(size))
...
>>> id_generator()
'G5G74W'
>>> id_generator(3, "6793YUIO")
'Y3U'

它是如何工作的?

我们导入 ,一个包含常见 ASCII 字符序列的模块,以及 一个处理随机生成的模块。stringrandom

string.ascii_uppercase + string.digits只是连接表示大写 ASCII 字符和数字的字符列表:

>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

然后,我们使用列表理解来创建“n”元素的列表:

>>> range(4) # range create a list of 'n' numbers
[0, 1, 2, 3]
>>> ['elem' for _ in range(4)] # we use range to create 4 times 'elem'
['elem', 'elem', 'elem', 'elem']

在上面的示例中,我们用于创建列表,但我们不在函数中,因此Python不会在内存中创建列表,而是动态生成元素,一个接一个(这里详细介绍)。[id_generator

而不是要求创建'n'乘以字符串,我们将要求Python创建'n'乘以从一系列字符中选择的随机字符:elem

>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'

因此,实际上是创建一系列字符。从 中随机选取的字符:random.choice(chars) for _ in range(size)sizechars

>>> [random.choice('abcde') for _ in range(3)]
['a', 'b', 'b']
>>> [random.choice('abcde') for _ in range(3)]
['e', 'b', 'e']
>>> [random.choice('abcde') for _ in range(3)]
['d', 'a', 'c']

然后,我们只需用空字符串连接它们,这样序列就变成了一个字符串:

>>> ''.join(['a', 'b', 'b'])
'abb'
>>> [random.choice('abcde') for _ in range(3)]
['d', 'c', 'b']
>>> ''.join(random.choice('abcde') for _ in range(3))
'dac'

答案 2

这个堆栈溢出问题是“随机字符串Python”的当前Google结果。目前最重要的答案是:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

这是一种很好的方法,但随机的PRNG在加密上并不安全。我假设许多研究这个问题的人都希望生成用于加密或密码的随机字符串。您可以通过在上面的代码中进行一些小的更改来安全地执行此操作:

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))

使用而不是只是随机使用 /dev/urandom 在 *nix 机器和 Windows 中。这些是加密安全的PRNG。而不是在需要安全PRNG的应用程序中使用可能是潜在的破坏性的,并且鉴于这个问题的普及,我敢打赌已经犯了很多次错误。random.SystemRandom()CryptGenRandom()random.choicerandom.SystemRandom().choice

如果您使用的是python3.6或更高版本,则可以使用MSeifert的答案中提到的new secrets模块:

''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))

模块文档还讨论了生成安全令牌的便捷方法和最佳实践