我正在寻找一种非常快速的方法来为表中的主键生成字母数字唯一ID。
会这样的吗?
def genKey():
hash = hashlib.md5(RANDOM_NUMBER).digest().encode("base64")
alnum_hash = re.sub(r'[^a-zA-Z0-9]', "", hash)
return alnum_hash[:16]
什么是产生随机数的好方法?如果我以microtime为基础,我必须考虑从不同实例同时多次调用genKey()的可能性。
或者有更好的方法来做这一切吗?
因为没有一个答案为你提供一个由字符0-9,a-z,A-Z组成的随机字符串:这是一个工作解决方案,它将给你一个约。 4.5231285 e + 74键:
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)
你可以用这个:
>>> import random
>>> ''.join(random.choice('0123456789ABCDEF') for i in range(16))
'E2C6B2E19E4A7777'
无法保证生成的密钥是唯一的,因此在原始插入失败的情况下,您应准备好使用新密钥重试。此外,您可能需要考虑使用确定性算法从自动递增的id生成字符串,而不是使用随机值,因为这将保证您的唯一性(但它也会提供可预测的键)。
看看uuid module(Python 2.5+)。
一个简单的例子:
>>> import uuid
>>> uid = uuid.uuid4()
>>> uid.hex
'df008b2e24f947b1b873c94d8a3f2201'
请注意,OP要求使用16个字符的字母数字字符串,但UUID4字符串长度为32个字符。您不应截断此字符串,而是使用完整的32个字符。
对于随机数,一个很好的来源是os.urandom
:
>> import os
>> import hashlib
>> random_data = os.urandom(128)
>> hashlib.md5(random_data).hexdigest()[:16]
在2016年12月发布的Python 3.6中,引入了secrets
模块。
您现在可以通过以下方式生成随机令牌:
import secrets
secrets.token_hex(16)
从Python文档:
secrets
模块用于生成适用于管理密码,帐户身份验证,安全令牌和相关机密等数据的加密强随机数。特别是,
secrets
应优先于random
模块中的默认伪随机数生成器使用,https://docs.python.org/3/library/secrets.html模块专为建模和模拟而非安全或加密而设计。
>>> import random
>>> ''.join(random.sample(map(chr, range(48, 57) + range(65, 90) + range(97, 122)), 16))
'CDh0geq3NpKtcXfP'
每次调用时此值增加1(它都会回绕)。确定存储值的最佳位置取决于您使用它的方式。您可能会发现import uuid
print uuid.uuid4().hex[:16].upper()
感兴趣的解释,因为它不仅讨论Guids如何工作,还讨论如何制作更小的Guids。
简短的回答是:将这些字符中的一些用作时间戳,将其他字符用作“uniquifier”,每次调用uid生成器时,值增加1。
只需使用python内置的uuid:
uuid
如果UUID可以用于您的目的,请使用内置的>>> import uuid
>>> str(uuid.uuid4().get_hex().upper()[0:16])
'40003A9B8C3045CA'
包。
qazxswpoi