为了方便批量管理bt,我一般会选择用更方便的磁力链接来添加,但是有些站点只提供种子文件,所以就需要将种子转换为磁链,这两个东西实际上是可以互相转换的,通过通用库就可以实现
其实本质上,.torrent 文件是一个采用 Bencode 编码格式的字典容器,它是一个打包好的信息表,里面详细记录了文件的元数据。在这个容器中,包含着如 tracker 服务器地址、创建时间等外围信息,但最核心的部分是“info”字典键。这个 info 区域包含了下载内容的实际结构描述,例如文件名、文件大小以及将文件切片后每一块的校验值。磁力链接的设计初衷则是为了实现去中心化的资源索引,不再依赖一个实体文件来告诉客户端去哪里下载,而是告诉客户端“我要找具有特定指纹的资源”,通过dht网络获取到实际的信息。这个“指纹”正是 Info Hash。也不用担心没有详细的元信息会获取不到bt,如果真的获取不到,即使有元信息你也只能看到一些文件名,实际上已经死种了
所以接下来转换的原理就很简单了:磁力链接的核心部分(即 xt=urn:btih: 之后的字符)实际上就是 .torrent 文件中 info 字典区域的 SHA-1 哈希值。换句话说,.torrent 文件是包含完整信息的本体,而磁力链接则是从原件核心区域提取出来的标识符。因此,将种子转换为磁链的过程,就是数据提取与哈希计算,给种子一个身份证号:读取种子文件,剥离出 info 字典的原始二进制数据,对其进行 SHA-1 运算,最后拼接上协议头即可。
可以通过 Python 的 bencodepy 库来解析 Bencode 结构(可以通过 pip install bencodepy 安装)。以二进制模式读取文件;其次解析结构找到 info 字段;最后不能直接对解析后的字典对象进行哈希,因为需要保证正确的字节顺序,必须将 info 字典重新编码回原始的 Bencode 二进制字节流,然后通过 hashlib 库计算出 SHA-1 值。
import sys
import hashlib
import binascii
import bencodepy
def torrent_to_magnet(torrent_path):
try:
with open(torrent_path, 'rb') as f:
torrent_data = f.read()
metadata = bencodepy.decode(torrent_data)
if b'info' not in metadata:
return "错误:该文件似乎不是有效的种子文件,缺少 info 字段。"
info_data = metadata[b'info']
raw_info_bytes = bencodepy.encode(info_data)
sha1_hash = hashlib.sha1(raw_info_bytes).digest()
hex_hash = binascii.hexlify(sha1_hash).decode('utf-8')
file_name = "Unknown"
if b'name' in info_data:
try:
file_name = info_data[b'name'].decode('utf-8')
except:
file_name = str(info_data[b'name'])
# xt: Exact Topic, urn: Uniform Resource Name, btih: BitTorrent Info Hash
magnet_link = f"magnet:?xt=urn:btih:{hex_hash}&dn={file_name}"
return magnet_link
except Exception as e:
return f"转换过程中发生错误: {str(e)}"
if __name__ == "__main__":
# 将这里的路径替换为你实际的 .torrent 文件路径
file_path = "example.torrent"
#也可以在命令行中通过参数添加你的文件路径
if len(sys.argv) > 1:
file_path = sys.argv[1]
print(f"正在处理文件: {file_path}")
link = torrent_to_magnet(file_path)
print("\n生成的磁力链接:\n")
print(link)
else:
print("请在命令行中提供种子文件路径,或修改脚本中的 file_path 变量。")

Comments NOTHING