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

ens*_*are 56 python random hash

我正在寻找一种非常快速的方法来为表中的主键生成字母数字唯一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]
Run Code Online (Sandbox Code Playgroud)

什么是产生随机数的好方法?如果我以microtime为基础,我必须考虑从不同实例同时调用genKey()的几次.

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

Dav*_*han 83

因为没有一个答案为你提供一个由字符0-9,az,AZ组成的随机字符串:这是一个工作解决方案,它将给你约.4.5231285e + 74键:

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

在不知道ASCII代码的情况下,它也非常易读.

从那以后有一个更短的版本python 3.6.2:

import random, string
x = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
print(x)
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 46

你可以用这个:

>>> import random
>>> ''.join(random.choice('0123456789ABCDEF') for i in range(16))
'E2C6B2E19E4A7777'
Run Code Online (Sandbox Code Playgroud)

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

  • @prometheus.是'os.urandom`而不是伪随机? (7认同)
  • 也许显而易见,但"确定性"并不意味着独特,你必须实际检查算法是否有很长的重复周期.`get_key = lambda n:n%10`是确定性的,但不是唯一的长期. (3认同)

Chr*_*heD 33

看看uuid模块(Python 2.5+).

一个简单的例子:

>>> import uuid
>>> uid = uuid.uuid4()
>>> uid.hex
'df008b2e24f947b1b873c94d8a3f2201'
Run Code Online (Sandbox Code Playgroud)

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

  • 这是32个字符,Guids的截断是不安全的. (7认同)

And*_*dyP 12

有一个官方食谱

import string
import secrets
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for i in range(16))
print(password)
Run Code Online (Sandbox Code Playgroud)

这将创建类似于 的输出'STCT3jdDUkppph03'

  • 我想这是现​​在最好的答案。更“恰当”的‘随机’;比“token_hex”更密集。 (3认同)

Bra*_*mul 8

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

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

import secrets

secrets.token_hex(16)
Run Code Online (Sandbox Code Playgroud)

从Python文档:

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

特别是,secrets应该优先使用random模块中默认的伪随机数生成器,该生成器是为建模和仿真而设计的,而不是安全性或加密技术。

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

  • 文档字符串:“返回十六进制的随机文本字符串。该字符串具有 *nbytes* 随机字节,每个字节转换为两个十六进制数字。如果 *nbytes* 为“无”或未提供,则使用合理的默认值。” 意思是“32 == len(secrets.token_hex(16))”。 (3认同)

rlo*_*tun 6

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

 >> import os
 >> import hashlib
 >> random_data = os.urandom(128)
 >> hashlib.md5(random_data).hexdigest()[:16]
Run Code Online (Sandbox Code Playgroud)