有效地生成一个16个字符的字母数字字符串

问题描述 投票:47回答:9

我正在寻找一种非常快速的方法来为表中的主键生成字母数字唯一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()的可能性。

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

python hash random
9个回答
75
投票

因为没有一个答案为你提供一个由字符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)

46
投票

你可以用这个:

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

无法保证生成的密钥是唯一的,因此在原始插入失败的情况下,您应准备好使用新密钥重试。此外,您可能需要考虑使用确定性算法从自动递增的id生成字符串,而不是使用随机值,因为这将保证您的唯一性(但它也会提供可预测的键)。


32
投票

看看uuid module(Python 2.5+)。

一个简单的例子:

>>> import uuid
>>> uid = uuid.uuid4()
>>> uid.hex
'df008b2e24f947b1b873c94d8a3f2201'

请注意,OP要求使用16个字符的字母数字字符串,但UUID4字符串长度为32个字符。您不应截断此字符串,而是使用完整的32个字符。


6
投票

对于随机数,一个很好的来源是os.urandom

 >> import os
 >> import hashlib
 >> random_data = os.urandom(128)
 >> hashlib.md5(random_data).hexdigest()[:16]

6
投票

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


3
投票

2
投票

每次调用时此值增加1(它都会回绕)。确定存储值的最佳位置取决于您使用它的方式。您可能会发现import uuid print uuid.uuid4().hex[:16].upper() 感兴趣的解释,因为它不仅讨论Guids如何工作,还讨论如何制作更小的Guids。

简短的回答是:将这些字符中的一些用作时间戳,将其他字符用作“uniquifier”,每次调用uid生成器时,值增加1。


0
投票

只需使用python内置的uuid:

uuid

-1
投票

Simply use python builtin uuid:

如果UUID可以用于您的目的,请使用内置的>>> import uuid >>> str(uuid.uuid4().get_hex().upper()[0:16]) '40003A9B8C3045CA' 包。

单线解决方案:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.