美文网首页
种子批量转磁链-javascript实现

种子批量转磁链-javascript实现

作者: 随喜公子 | 来源:发表于2019-04-03 18:37 被阅读0次

    Torrent

    历史

    该技术由美国的程序员布莱姆·科亨于2001年4月时发布,并于2001年7月2日时首次正式应用。

    原理

    普通的HTTP/FTP下载使用TCP/IP协议,BitTorrent协议是架构于TCP/IP协议之上的一个P2P文件传输通信协议,处于TCP/IP结构的应用层。
    根据BitTorrent协议,文件发布者会根据要发布的文件生成提供一个.torrent文件,即种子文件,也简称为“种子”。

    组成

    种子文件本质是文本文件,包括Tracker和文件信息两个部分:
    Tracker服务器保存所有正在下载文件的客户端的地址,有人新建连接时,会将地址反馈给新的连接。
    文件信息是用Bencode进行编码,是要下载的文件的索引。

    Tracker信息
    • Tracker服务器地址
    • Tracker服务器设置
    文件信息
    • announce - tracker的URL
    • info - 该条映射到一个字典,该字典的键将取决于共享的一个或多个文件
      • name - 建议保存到的文件和目录名称
      • piece length - 每个文件块的字节数。通常为256KB = 262144B
      • pieces - 每个文件块的SHA-1的集成Hash。因为SHA-1会返回160-bit的Hash,所以pieces将会得到1个160-bit的整数倍的字符串。和一个length(相当于只有一个文件正在共享)或files(相当于当多个文件被共享):
      • length - 文件的大小(以字节为单位)
      • files - 一个字典的列表(每个字典对应一个文件)与以下的键
        • path - 一个对应子目录名的字符串列表,最后一项是实际的文件名称
        • length - 文件的大小(以字节为单位)

    info-hash:每一个种子唯一的编码,由info字段的数据计算而成。

    DHT网络

    DHT全称为分布式哈希表(Distributed Hash Table),是一种分布式存储方法。在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个DHT网络的寻址和存储。

    磁链

    历史

    这个标准的草稿出现于2002年,是为了对eDonkey2000的“ed2k:”和Freenet的“freenet:”两个URI格式进行“厂商与项目中立化”(vendor- and project-neutral generalization)而制定的。同时这个标准也尝试紧密地跟进IETF官方的URI标准。

    原理

    特点:

    • 分布式。
    • 不依赖于ip地址
    • 没有中心服务器
    • 开源

    组成

    磁力链接由一组参数组成,参数间的顺序没有讲究,其格式与在HTTP链接末尾的查询字符串相同。最常见的参数是"xt",是"exact topic"的缩写,通常是一个特定文件的内容散列函数值形成的URN。

    magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C
    

    其值是Base32编码的文件的SHA-1散列。

    基本描述

    magnet:? xl = [字节大小]& dn = [文件名(已编码URL)]& xt = urn: tree: tiger: [ TTH hash(Base32)]
    

    由参数来指定相关的内容:

    • dn(显示名称)- 文件名
    • xl(绝对长度)- 文件字节数
    • xt(eXact Topic)- 包含文件散列函数值的URN。磁力链接的这部分最重要。用于寻找和验证包含着磁力链接中的文件。
    • as(可接受来源) - 在线文件的网络链接
    • xs(绝对资源)- P2P链接
    • kt(关键字)- 用于搜索的关键字
    • mt(文件列表)- 链接到一个包含磁力链接的元文件 (MAGMA - MAGnet MAnifest)
    • tr(Tracker地址)- BT下载的Tracker URL
    • btih(BitTorrent Info Hash):种子的info_hash,转换磁链时就是计算它

    开发工具和平台

    计算提取info_hash

    关键:info字段的值,必须先解码,再对info字段的值编码,然后才计算hash。直接从文件中删除其他部分行不通。

    js

    bencode库

    npm install bencode
    

    如果装了nvm,则-g全局安装会装在.nvm文件夹下。否则,就装在用户目录的node_module下。

    sha-1库

    npm install js-sha1
    

    实现代码

    输出

    提取的磁力链接存放在种子目录下名为magnets.txt的文件中

    使用
    node t2m.js <种子文件夹路径>
    
    js代码
    var fs = require("fs");
    var bencode = require('bencode');
    var sha1 = require('js-sha1');
    var arguments = process.argv.splice(2); //获取命令行参数,第三个元素是带的参数
    
    outMagnets(getMagnets(arguments), arguments);
    
    // 获取磁链链接,arguments为文件夹路径
    function getMagnets(arguments) {
        var fileslist = fs.readdirSync(arguments.toString());
        var magnetlist = new Array();
    
        for (var f in fileslist) {
            var torrentfile = null;
            var filename = fileslist[f].toString();
            if (filename.includes(".torrent")) {
                var filepath = arguments.toString() + '/' + filename;
                var magnet = getInfoHash(filepath);
                if (magnet) {
                    magnetlist.push(magnet);
                }
                //console.log(magnet);
            }
        }
        return magnetlist;
    }
    
    // 将结果输出为txt
    function outMagnets(magnets, path) {
        if (magnets.length > 0) {
            var writebuffer = Buffer.from(arrayToString(magnets, '\n'));
            var savepath = path.toString() + '/' + "magnets.txt";
            var writesteam = fs.createWriteStream(savepath);
            writesteam.write(writebuffer, 'utf-8');
            writesteam.end();
            writesteam.on('finish', function () {
                console.log("写入完成");
            });
            writesteam.on('error', function (err) {
                console.log(err);
            });
        }
    }
    
    // buffer只能输出字符,所以必须将字符数组转换为字符形式,seq为分隔符
    function arrayToString(arr, seq) {
        var str_value = null;
        for (a of arr) {
            var astr = a.toString();
            if (str_value) {
                str_value = str_value + seq + astr;
            } else {
                str_value = astr;
            }
        }
        return str_value;
    }
    // 获取种子文件的info_hash值,有一个解密,再加密的过程
    function getInfoHash(torrentfile) {
        var result = bencode.decode(fs.readFileSync(torrentfile));
        if (result) {
            var info = result['info']; //info 字典
            var info_hash = sha1(bencode.encode(info));
            var magnet = "magnet:?xt=urn:btih:" + info_hash.toString();
            return magnet;
        } else {
            return null;
        }
    }
    

    python

    bencode库

    gittub
    安装:

    pip3 install py3-bencode
    

    实现代码

    from bencode import bencode, bdecode
    from io import BytesIO
    import hashlib
    
    objTorrentFile = open("test.torrent", "rb")
    decodedDict = bdecode(objTorrentFile.read())
    
    info_hash = hashlib.sha1(bencode(decodedDict["info"])).hexdigest()
    print(info_hash)
    
    

    在解码提取出info后,似乎还需要编码后,再求hash值

    参考网址

    磁力链接wiki
    磁力链接转换为种子文件
    官方种子格式说明
    种子格式详解
    bencode详解
    python bencode可用
    bencode-gitthub
    bencode源码
    js-bencode 实现
    wiki-bencode

    相关文章

      网友评论

          本文标题:种子批量转磁链-javascript实现

          本文链接:https://www.haomeiwen.com/subject/ogxtiqtx.html