种子批量转磁链-javascript实现

2019-04-03  本文已影响0人  随喜公子

Torrent

历史

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

原理

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

组成

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

Tracker信息
文件信息

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

DHT网络

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

磁链

历史

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

原理

特点:

组成

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

magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C

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

基本描述

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

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

开发工具和平台

计算提取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

上一篇下一篇

猜你喜欢

热点阅读