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

时间:2010-03-24 20:40:17

标签: python hash random

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

还是有更好的方法来做这一切吗?

11 个答案:

答案 0 :(得分:71)

因为没有一个答案为你提供一个由字符0-9,a-z,A-Z组成的随机字符串:这是一个工作解决方案,可以给你约。 4.5231285e + 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)

答案 1 :(得分:46)

您可以使用:

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

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

答案 2 :(得分:32)

查看uuid module(Python 2.5 +)。

一个简单的例子:

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

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

答案 3 :(得分:6)

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

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

答案 4 :(得分:4)

>>> import random
>>> ''.join(random.sample(map(chr, range(48, 57) + range(65, 90) + range(97, 122)), 16))
'CDh0geq3NpKtcXfP'

答案 5 :(得分:2)

每次调用时此值增加1(包装)。确定存储值的最佳位置取决于您使用它的方式。您可能会发现this感兴趣的解释,因为它不仅讨论了Guids的工作原理,还讨论了如何制作较小的Guids。

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

答案 6 :(得分:0)

只需使用内置的 uuid

import uuid
print uuid.uuid4().hex[:16].upper()

答案 7 :(得分:0)

在2016年12月发布的Python 3.6中,引入了secrets模块。

您现在可以通过以下方式生成随机令牌:

import secrets

secrets.token_hex(16)

来自Python文档:

  

secrets模块用于生成加密强度高的   适用于管理数据(例如密码,帐户)的随机数   身份验证,安全令牌和相关机密。

     

尤其是,secrets应该优先于默认值   random模块中的伪随机数生成器   用于建模和仿真,而不是安全性或加密。

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

答案 8 :(得分:0)

import math
import secrets


def random_alphanum(length: int) -> str:
    if length == 0:
        return ''
    elif length < 0:
        raise ValueError('negative argument not allowed')
    else:
        text = secrets.token_hex(nbytes=math.ceil(length / 2))
        is_length_even = length % 2 == 0
        return text if is_length_even else text[1:]
  • uuid 方法效率低下且有局限性,因为 uuid 只返回 36 个字符,然后被截断。
  • 默认的伪随机数生成器不适用于安全或加密应用,有一个标准模块机密可用,专为这些应用而设计。

答案 9 :(得分:-1)

您还可以尝试仅使用numpy的方法

import numpy as np

 ''.join([ chr(ord('a')+np.random.randint(24)) for i in range(0,16)])

答案 10 :(得分:-2)

只需使用python builtin uuid:

如果UUID可以用于您的目的,请使用内置的uuid包。

One Line Solution:

>>> import uuid
>>> str(uuid.uuid4().get_hex().upper()[0:16])
'40003A9B8C3045CA'