我试图实现一些Tor .onion地址的随机生成器,这些生成器涉及生成80位数字以创建16个字符的哈希值。
如何在Python中定义这样的变量?
" 16个字符的哈希值可以由字母表中的任何字母组成 十进制数字以2开头并以7结尾,从而表示 base32中的80位数字。"
链接:
答案 0 :(得分: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。
答案 1 :(得分: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
答案 2 :(得分: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)])