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

1 投票
3 回答
1409 浏览
提问于 2025-04-18 17:46

我正在尝试实现一个随机生成器,用来生成Tor.onion地址,这个过程需要生成80位的数字来创建16个字符的哈希值。

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

.onion格式

“16个字符的哈希值可以由字母表中的任何字母和以2开头、以7结尾的十进制数字组成,这样就能表示一个以32为底的80位数字。”

相关链接:

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中也可以用。

撰写回答