如何在Python中定义80位长变量来生成随机的.onion地址?

时间:2014-08-19 10:32:45

标签: python tor custom-data-type

我试图实现一些Tor .onion地址的随机生成器,这些生成器涉及生成80位数字以创建16个字符的哈希值。

如何在Python中定义这样的变量?

.onion format

  

" 16个字符的哈希值可以由字母表中的任何字母组成   十进制数字以2开头并以7结尾,从而表示   base32中的80位数字。"

链接:

3 个答案:

答案 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)])