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

新手上路,请多包涵

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

  • 6U1S75
  • 4Z4UKK
  • U911K4

原文由 Hellnar 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 305
2 个回答

一行回答:

 ''.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'

它是如何工作的 ?

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

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']

在上面的示例中,我们使用 [ 创建列表,但我们不在 id_generator 函数中,因此 Python 不会在内存中创建列表,而是在苍蝇,一只一只(更多关于 这里)。

不是要求创建 ‘n’ 次字符串 elem ,我们将要求 Python 创建 ‘n’ 次随机字符,从字符序列中挑选:

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

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

 >>> [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'

原文由 Ignacio Vazquez-Abrams 发布,翻译遵循 CC BY-SA 4.0 许可协议

这个 Stack Overflow 问题是当前谷歌搜索“随机字符串 Python”的最高结果。当前的最佳答案是:

 ''.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))

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

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

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

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

原文由 Randy Marsh 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题