高效生成16字符的字母数字字符串

117 投票
13 回答
153208 浏览
提问于 2025-04-15 20:49

我在寻找一种非常快速的方法来生成一个字母数字组合的唯一标识符,用作表格中的主键。

像这样的方法可行吗?

def genKey():
    hash = hashlib.md5(RANDOM_NUMBER).digest().encode("base64")
    alnum_hash = re.sub(r'[^a-zA-Z0-9]', "", hash)
    return alnum_hash[:16]

有没有什么好的方法来生成随机数字?如果我基于微秒时间来生成,就得考虑到可能会有多个不同的实例同时调用genKey()。

或者有没有更好的方法来做到这一切?

13 个回答

45

在2016年12月发布的Python 3.6版本中,新增了一个叫做secrets的模块。

你现在可以用这种方式生成一个随机的令牌:

import secrets

secrets.token_hex(16)

根据Python的官方文档:

secrets模块用于生成强随机数,这些随机数在处理密码、账户认证、安全令牌和相关秘密信息时非常合适。

特别是,secrets模块应该优先于random模块中的默认伪随机数生成器,因为后者是为了建模和模拟而设计的,不适合用于安全或加密。

https://docs.python.org/3/library/secrets.html

64

你可以使用这个:

>>> import random
>>> ''.join(random.choice('0123456789ABCDEF') for i in range(16))
'E2C6B2E19E4A7777'

生成的键不一定是唯一的,所以如果原来的插入失败,你需要准备好重新尝试用一个新的键。此外,你可能想考虑使用一种确定性算法,从一个自动递增的ID生成字符串,而不是使用随机值,这样可以确保键的唯一性(不过这样生成的键是可预测的)。

195

因为没有答案提供一个由数字0-9、小写字母a-z和大写字母A-Z组成的随机字符串,这里有一个有效的解决方案,可以生成大约62的16次方(也就是大约4.76724乘以10的28次方)个密钥:

import random, string
x = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(16))
print(x)

这个代码即使不记得ASCII码也很容易理解。

自从python 3.6.2版本以来,还有一个更简短的版本:

import random, string
x = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
print(x)

撰写回答