将bt种子转换为磁力链接

Hexa 教程 最后更新于 2026-01-20 71 次阅读


为了方便使用,开发了一版web应用,可以直接在线转换,下方传送门直达

为了方便批量管理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 变量。")