如何在Python中定义80位长变量以生成随机.onion地址?
3 个回答
2
因为你实际上需要的是80位哈希值的字母数字表示,所以直接选择基于32的数字就可以了。
digits = "abcdefghijklmnopqrstuvwxyz234567"
address = "".join(random.choice(digits) for _ in range(16))
我发现通过避免重复查找random.choice
的名字,并使用列表推导式而不是把生成器传给"".join
,速度提高了15%。
from random import choice
digits = "abcdefghijklmnopqrstuvwxyz234567"
address = "".join([choice(digits) for _ in range(16)])
3
你可以用下面的方法生成一个包含10个字节的、编码为80位随机数的序列:
import struct
import random
number = random.randint(0, 2**80)
data = struct.pack("qH", number >> 16, number & 16)
更新
抱歉,上面的部分没有考虑到密钥的Base32编码 - 如果不使用Python的字符串编码工具(可以参考metatoaster的回答),那么一个简洁易读的形式是:
import string
import random
digits = string.lowercase + "234567"
res = ""
n = random.randrange(2**80)
for _ in range(16):
res += digits[n & 0b11111]
n >>= 5
4
如果你在用Python3,这里有一行代码可以帮你搞定。
import base64
import codecs
import random
data = base64.b32encode(
codecs.decode(codecs.encode(
'{0:020x}'.format(random.getrandbits(80))
), 'hex_codec')
)
解释一下:你可以用 random.getrandbits
这个函数来获取80个随机的位(比特),然后把它们转换成二进制形式。这个过程需要先通过十六进制编码,再使用 base64.b32encode
函数,这个函数可以把数据按照 RFC 3548 的标准转换成你想要的base32编码。
这个方法在Python 2中也可以用。