用于读取 torrent 文件的 PHP 模块

发布于 2024-07-06 19:42:03 字数 1511 浏览 10 评论 0 原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

虐人心 2024-07-13 19:42:03

我曾在自己制作的一个小网站中使用过这些功能。 我想我是用一个名为 OpenTracker 的 php Bittorrent 跟踪器或其他东西找到了它们,但找不到网站...

不过,您不会在 torrent 文件中找到播种器。 种子文件只包含有关文件、哈希码和长度等的信息。我相信还有一些跟踪器信息。 您必须从跟踪器获得多少播种机等。 您可以在 BitTorrent.org 上阅读有关协议的信息。 我相信,通信是经过编码的,因此您也可以使用这些函数来实现这一点。 这意味着您只需弄清楚要发送什么内容即可取回您想要的内容。

注意:这三个函数不是我写的。 就像我说的,我在一个开源 torrent 跟踪器的源代码中找到了它们。 这些函数没有注释,但函数名称与 torrent 文件结果上的 print_r 一起,您知道其中的信息应该足以理解如何使用它们。 我在底部添加了一些示例代码来展示我如何使用它们。 他们工作了。

function bdecode($str) {
    $pos = 0;
    return bdecode_r($str, $pos);
}

function bdecode_r($str, &$pos) {
    $strlen = strlen($str);
    if (($pos < 0) || ($pos >= $strlen)) {
            return null;
    }
    else if ($str{$pos} == 'i') {
            $pos++;
            $numlen = strspn($str, '-0123456789', $pos);
            $spos = $pos;
            $pos += $numlen;
            if (($pos >= $strlen) || ($str{$pos} != 'e')) {
                    return null;
            }
            else {
                    $pos++;
                    return intval(substr($str, $spos, $numlen));
            }
    }
    else if ($str{$pos} == 'd') {
            $pos++;
            $ret = array();
            while ($pos < $strlen) {
                    if ($str{$pos} == 'e') {
                            $pos++;
                            return $ret;
                    }
                    else {
                            $key = bdecode_r($str, $pos);
                            if ($key == null) {
                                    return null;
                            }
                            else {
                                    $val = bdecode_r($str, $pos);
                                    if ($val == null) {
                                            return null;
                                    }
                                    else if (!is_array($key)) {
                                            $ret[$key] = $val;
                                    }
                            }
                    }
            }
            return null;
    }
    else if ($str{$pos} == 'l') {
            $pos++;
            $ret = array();
            while ($pos < $strlen) {
                    if ($str{$pos} == 'e') {
                            $pos++;
                            return $ret;
                    }
                    else {
                            $val = bdecode_r($str, $pos);
                            if ($val == null) {
                                    return null;
                            }
                            else {
                                    $ret[] = $val;
                            }
                    }
            }
            return null;
    }
    else {
            $numlen = strspn($str, '0123456789', $pos);
            $spos = $pos;
            $pos += $numlen;
            if (($pos >= $strlen) || ($str{$pos} != ':')) {
                    return null;
            }
            else {
                    $vallen = intval(substr($str, $spos, $numlen));
                    $pos++;
                    $val = substr($str, $pos, $vallen);
                    if (strlen($val) != $vallen) {
                            return null;
                    }
                    else {
                            $pos += $vallen;
                            return $val;
                    }
            }
    }
}

function bencode($var) {
    if (is_int($var)) {
            return 'i' . $var . 'e';
    }
    else if (is_array($var)) {
            if (count($var) == 0) {
                    return 'de';
            }
            else {
                    $assoc = false;
                    foreach ($var as $key => $val) {
                            if (!is_int($key)) {
                                    $assoc = true;
                                    break;
                            }
                    }
                    if ($assoc) {
                            ksort($var, SORT_REGULAR);
                            $ret = 'd';
                            foreach ($var as $key => $val) {
                                    $ret .= bencode($key) . bencode($val);
                            }
                            return $ret . 'e';
                    }
                    else {
                            $ret = 'l';
                            foreach ($var as $val) {
                                    $ret .= bencode($val);
                            }
                            return $ret . 'e';
                    }
            }
    }
    else {
            return strlen($var) . ':' . $var;
    }
}

一些示例用法:

# Read a file
$content = file_get_contents("file.torrent");
$content_d = bdecode($content);

# Check if bdecode succeeded
if(empty($content_d)) exit('Something is wrong with the torrent. BDecode failed.');

# Calculate info_hash
$info_hash = sha1(bencode($content_d['info']), true);

# Calculate length
$length = 0;
function add_length($value, $key)
{
    global $length;
    if($key == 'length') $length += $value;
}
array_walk_recursive($content_d, 'add_length');

I have used these functions in a small website I made once. Think I found them with a php bittorrent tracker called OpenTracker or something, but can't find the website...

You wont find the seeders in the torrent file though. The torrent file just contain info about the files, hash codes and lengths etc. And some tracker information I believe. How many seeders and such you will have to get from the tracker. You can read about the protocal at BitTorrent.org. The communication is, I believe, bencoded, so you can use these functions for that as well. Which means you just have to figure out what to send to get what you want back.

NOTE: I did not write these three functions. Like I said, I found them in the source of an open source torrent tracker. The functions are not commented, but the function names together with a print_r on the result of a torrent file you know the info inshould be enough to understand how to use them. I added some example code at the bottom to show how I used them. And they worked.

function bdecode($str) {
    $pos = 0;
    return bdecode_r($str, $pos);
}

function bdecode_r($str, &$pos) {
    $strlen = strlen($str);
    if (($pos < 0) || ($pos >= $strlen)) {
            return null;
    }
    else if ($str{$pos} == 'i') {
            $pos++;
            $numlen = strspn($str, '-0123456789', $pos);
            $spos = $pos;
            $pos += $numlen;
            if (($pos >= $strlen) || ($str{$pos} != 'e')) {
                    return null;
            }
            else {
                    $pos++;
                    return intval(substr($str, $spos, $numlen));
            }
    }
    else if ($str{$pos} == 'd') {
            $pos++;
            $ret = array();
            while ($pos < $strlen) {
                    if ($str{$pos} == 'e') {
                            $pos++;
                            return $ret;
                    }
                    else {
                            $key = bdecode_r($str, $pos);
                            if ($key == null) {
                                    return null;
                            }
                            else {
                                    $val = bdecode_r($str, $pos);
                                    if ($val == null) {
                                            return null;
                                    }
                                    else if (!is_array($key)) {
                                            $ret[$key] = $val;
                                    }
                            }
                    }
            }
            return null;
    }
    else if ($str{$pos} == 'l') {
            $pos++;
            $ret = array();
            while ($pos < $strlen) {
                    if ($str{$pos} == 'e') {
                            $pos++;
                            return $ret;
                    }
                    else {
                            $val = bdecode_r($str, $pos);
                            if ($val == null) {
                                    return null;
                            }
                            else {
                                    $ret[] = $val;
                            }
                    }
            }
            return null;
    }
    else {
            $numlen = strspn($str, '0123456789', $pos);
            $spos = $pos;
            $pos += $numlen;
            if (($pos >= $strlen) || ($str{$pos} != ':')) {
                    return null;
            }
            else {
                    $vallen = intval(substr($str, $spos, $numlen));
                    $pos++;
                    $val = substr($str, $pos, $vallen);
                    if (strlen($val) != $vallen) {
                            return null;
                    }
                    else {
                            $pos += $vallen;
                            return $val;
                    }
            }
    }
}

function bencode($var) {
    if (is_int($var)) {
            return 'i' . $var . 'e';
    }
    else if (is_array($var)) {
            if (count($var) == 0) {
                    return 'de';
            }
            else {
                    $assoc = false;
                    foreach ($var as $key => $val) {
                            if (!is_int($key)) {
                                    $assoc = true;
                                    break;
                            }
                    }
                    if ($assoc) {
                            ksort($var, SORT_REGULAR);
                            $ret = 'd';
                            foreach ($var as $key => $val) {
                                    $ret .= bencode($key) . bencode($val);
                            }
                            return $ret . 'e';
                    }
                    else {
                            $ret = 'l';
                            foreach ($var as $val) {
                                    $ret .= bencode($val);
                            }
                            return $ret . 'e';
                    }
            }
    }
    else {
            return strlen($var) . ':' . $var;
    }
}

Some example usage:

# Read a file
$content = file_get_contents("file.torrent");
$content_d = bdecode($content);

# Check if bdecode succeeded
if(empty($content_d)) exit('Something is wrong with the torrent. BDecode failed.');

# Calculate info_hash
$info_hash = sha1(bencode($content_d['info']), true);

# Calculate length
$length = 0;
function add_length($value, $key)
{
    global $length;
    if($key == 'length') $length += $value;
}
array_walk_recursive($content_d, 'add_length');
酒解孤独 2024-07-13 19:42:03

Google 在 sourceforge 和 PHP 客户端 .org/browse/package/3138.html" rel="noreferrer">PHP 类上的此 torrent 类。 应该是你所需要的。

Google comes up with this PHP client on sourceforge and this torrent class on PHP classes. Should be all you need.

只是在用心讲痛 2024-07-13 19:42:03

Torrent 文件基本上是使用 BEncode 编码的嵌套字典。 BEncode 是一种简单的编码,有一些 BDecode PHP 类,例如 这个

torrent 文件的结构在 中描述BEP0003

请注意,torrent 文件不包含您提到的“Seeders”字段。 播种者列表是动态的,由跟踪服务器管理。 有了 torrent 的 hash_infotracker_url (均可从 torrent 文件获取),您可以向跟踪器发送抓取请求,它将在“完整”字段中返回播种器数量,请参阅< a href="http://wiki.theory.org/BitTorrentSpecification#Tracker_.27scrape.27_Convention" rel="noreferrer">跟踪器抓取约定。

Torrent files are basically nested dictionaries encoded with BEncode. BEncode is a simple encoding and there are a few BDecode PHP classes, like this one.

Structure of torrent file is described in BEP0003.

Note that torrent files don't contain "Seeders" field that you mention. The list of seeders is dynamic and is managed by tracker server. Having torrent's hash_info and tracker_url (both available from torrent file) you can send scrape-request to the tracker and it will return number of seeders in 'complete' field, see Tracker Scrape Convention.

倾其所爱 2024-07-13 19:42:03

该库包含一个可以很好地完成这项工作的子库:
http://www.binpress.com/app/phptracker/177

This library contains a sublibrary which does the job very well:
http://www.binpress.com/app/phptracker/177

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文