2009-04-24 40 views
77

我一直试图找到生成的Python,可以扩展以及随机字符串的一个更Python的方式。通常情况下,我看到类似的东西随机字符串(这是正确的?)

''.join(random.choice(string.letters) for i in xrange(len)) 

它很糟糕,如果你想产生长字符串。

我一直在想random.getrandombits了一段时间,并找出如何将其转换成一组位,则十六进制编码。使用python 2.6我遇到了没有记录的bitarray对象。不知何故,我得到它的工作,而且看起来非常快。

它产生在短短3秒左右我的笔记本上为50Mil一个随机字符串。

def rand1(leng): 
    nbits = leng * 6 + 1 
    bits = random.getrandbits(nbits) 
    uc = u"%0x" % bits 
    newlen = int(len(uc)/2) * 2 # we have to make the string an even length 
    ba = bytearray.fromhex(uc[:newlen]) 
    return base64.urlsafe_b64encode(str(ba))[:leng] 

编辑

heikogerlach指出,这是一个奇数导致此问题的字符。添加新代码以确保始终从hex发送偶数个十六进制数字。

,如果有这只是快了这样做的更好的办法仍然好奇。

+1

特定的长度如何使这一点,以便它只会包含数字,字母和强调? (这包括破折号)(对于i的x范围random.choice(string.letters + string.digits + “_”)(长度)) – wenbert 2010-12-30 06:49:07

+2

@wenbert ''。加入 – yanjost 2011-08-31 09:56:54

回答

132
import os 
random_string = os.urandom(string_length) 

,如果你需要的网址安全的字符串:

import os 
random_string = os.urandom(string_length).hex() 

(注random_string长度比在这种情况下STRING_LENGTH最大)

+0

阿!很简单。我不认为这是跨平台的,但显然是这样。 – mikelikespie 2009-04-24 09:17:42

+0

只需随访,这是非常奇怪的,但至少在OS X中,getrandbits方法快2-3倍。 – mikelikespie 2009-04-24 09:25:46

+9

这可能是因为操作系统。urandom将是一个密码安全的PRNG(通常是流密码),而随机是一个“正常”的PRNG,通常计算速度更快。 – Joey 2009-04-24 12:29:22

2

看来fromhex()方法预期偶数个十六进制数字。您的字符串长度为75个字符。 请注意,something[:-1]不包括最后一个元素!只需使用something[:]即可。

5

在Python.org从1023290 bug报告摘自:

junk_len = 1024 
junk = (("%%0%dX" % junk_len) % random.getrandbits(junk_len * 
8)).decode("hex") 

而且,看问题9236431023290

2

关于最后一个例子,以下修补程序,以确保该行是偶数长度,不管junk_len值如何:

junk_len = 1024 
junk = (("%%0%dX" % (junk_len * 2)) % random.getrandbits(junk_len * 8)).decode("hex") 
9

有时候uuid足够短,如果你不喜欢破折号,你可以alw ays.replace(“ - ”,“”),他们

from uuid import uuid4 

random_string = str(uuid4()) 

如果你想它没有破折号

random_string_length = 16 
str(uuid4()).replace('-', '')[:random_string_length]