torrent_decoder.class.php
Code: Select all
<?php
/**
* @Author: Scott Martin <sjm.dev1[at]gmail[dot]com>
* @Filename: torrent_decoder.class.php
* @Date: October 5th, 2010
*
* -- Description:
* This is a torrent decoder class used to extract .torrent files into an
* associative array of useable info.
*
* -- Usage:
* require_once 'torrent_decoder.class.php';
* $decoder = new torrent_decoder('path/to/file.torrent');
* $torrent = $decoder->decode();
* //print_r($torrent); //show all of the info provided by the torrent file
*
* -- Access Info:
* $torrent now contains an array of useful info, for example
* echo $torrent['announce']; //prints the announce URL
*
* @Liscense: GNU GPL V3
- Copyright (C) <2010> <Scott Martin>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class torrent_decoder
{
private $contents = '';
private $pos = 0;
/**
* When initiated the raw contents of the .torrent file are held
* in class member $contents.
*
* @access public
* @param $file - filename of torrent
* @return void
*/
function __construct($file)
{
$this->contents = @file_get_contents($file);
}
/**
* Starts the decoding method(s).
* Throws exception if contents cannot be opened, is empty, or file cannot
* be found.
*
* @access public
* @param void
* @return array
*/
function decode()
{
if (empty($this->contents))
{
throw new exception('Torrent file is empty, cannot be opened, or cannot be found.');
return;
}
$ret = $this->doChar();
return $ret;
}
/**
* Processes character at internal pointer position to check for an identifier.
* Possible identifiers are 'd', 'l', 'i', and 0-9
* Throws exception if an unknown character identifier is found.
*
* @access private
* @param void
* @return mixed
*/
private function doChar()
{
while ($this->contents[$this->pos] != 'e')
{
if ($this->contents[$this->pos] == 'd')
{
return $this->doDict();
}
elseif ($this->contents[$this->pos] == 'l')
{
return $this->doList();
}
elseif ($this->contents[$this->pos] == 'i')
{
return $this->doInt();
}
else
{
if (is_numeric($this->contents[$this->pos]))
{
return $this->doString();
} else
{
throw new exception('Unknown character \'' . $this->contents[$this->pos] . '\' at position ' . $this->pos);
return;
}
}
}
}
/**
* Processes dictionary 'd' identifier.
*
* @access private
* @param void
* @return array
*/
private function doDict()
{
$ret = array();
$this->pos++;
while ($this->contents[$this->pos] != 'e')
{
$key = $this->doString();
if ($this->contents[$this->pos] == 'd')
{
$ret[$key] = $this->doDict();
}
elseif ($this->contents[$this->pos] == 'l')
{
$ret[$key] = $this->doList();
}
elseif ($this->contents[$this->pos] == 'i')
{
$ret[$key] = $this->doInt();
} else
{
if (is_numeric($this->contents[$this->pos]))
{
$ret[$key] = $this->doString();
} else
{
throw new exception('Unknown character \'' . $this->contents[$this->pos] . '\' at position ' . $this->pos);
return;
}
}
}
$this->pos++;
return $ret;
}
/**
* Processes strings found.
*
* @access private
* @param void
* @return string
*/
private function doString()
{
$strlen = '';
while (is_numeric($this->contents[$this->pos]))
{
$strlen .= $this->contents[$this->pos];
$this->pos++;
}
if ($this->contents[$this->pos] == ':')
{
$this->pos++;
}
$strlen = intval($strlen);
$str = substr($this->contents, $this->pos, $strlen);
$this->pos = $this->pos + $strlen;
return $str;
}
/**
* Processes list 'l' identifiers and returns an array of
* items found in the list.
*
* @access private
* @param void
* @return array
*/
private function doList()
{
$ret = array();
$this->pos++;
while ($this->contents[$this->pos] != 'e')
{
$ret[] = $this->doChar();
}
$this->pos++;
return $ret;
}
/**
* Processes integer 'i' identifier.
*
* @access private
* @param void
* @return integer
*/
private function doInt()
{
$this->pos++;
$int = '';
while ($this->contents[$this->pos] != 'e')
{
$int .= $this->contents[$this->pos];
$this->pos++;
}
$int = intval($int);
$this->pos++;
return $int;
}
}Code: Select all
<?php
require_once 'torrent_decoder.class.php';
$decoder = new torrent_decoder('path/to/file.torrent');
$torrent = $decoder->decode();I created a torrent file from a digital picture folder and this is the output
Code: Select all
Array
(
[announce] => http://w1.example.com/track/announce
[announce-list] => Array
(
[0] => Array
(
[0] => http://w1.example.com/track/announce
[1] => http://w2.example.com/track/announce
)
)
[comment] => created by scott
[created by] => uTorrent/2040
[creation date] => 1286340941
[encoding] => UTF-8
[info] => Array
(
[files] => Array
(
[0] => Array
(
[length] => 361660
[path] => Array
(
[0] => 100_0806.JPG
)
)
[1] => Array
(
[length] => 380832
[path] => Array
(
[0] => 100_0807.JPG
)
)
[2] => Array
(
[length] => 375960
[path] => Array
(
[0] => 100_0808.JPG
)
)
[3] => Array
(
[length] => 390620
[path] => Array
(
[0] => 100_0809.JPG
)
)
[4] => Array
(
[length] => 187995
[path] => Array
(
[0] => 100_0811.JPG
)
)
[5] => Array
(
[length] => 337143
[path] => Array
(
[0] => 100_0812.JPG
)
)
[6] => Array
(
[length] => 401504
[path] => Array
(
[0] => 100_0813.JPG
)
)
[7] => Array
(
[length] => 403132
[path] => Array
(
[0] => 100_0814.JPG
)
)
[8] => Array
(
[length] => 407540
[path] => Array
(
[0] => 100_0815.JPG
)
)
[9] => Array
(
[length] => 394160
[path] => Array
(
[0] => 100_0816.JPG
)
)
[10] => Array
(
[length] => 350944
[path] => Array
(
[0] => 100_0817.JPG
)
)
[11] => Array
(
[length] => 362988
[path] => Array
(
[0] => 100_0818.JPG
)
)
[12] => Array
(
[length] => 412444
[path] => Array
(
[0] => 100_0819.JPG
)
)
[13] => Array
(
[length] => 395276
[path] => Array
(
[0] => 100_0820.JPG
)
)
[14] => Array
(
[length] => 356812
[path] => Array
(
[0] => 100_0821.JPG
)
)
[15] => Array
(
[length] => 371620
[path] => Array
(
[0] => 100_0822.JPG
)
)
[16] => Array
(
[length] => 363076
[path] => Array
(
[0] => 100_0823.JPG
)
)
[17] => Array
(
[length] => 315440
[path] => Array
(
[0] => 100_0824.JPG
)
)
[18] => Array
(
[length] => 351548
[path] => Array
(
[0] => 100_0825.JPG
)
)
[19] => Array
(
[length] => 337143
[path] => Array
(
[0] => 100_0826.JPG
)
)
[20] => Array
(
[length] => 934372
[path] => Array
(
[0] => 100_0827.JPG
)
)
[21] => Array
(
[length] => 949040
[path] => Array
(
[0] => 100_0828.JPG
)
)
[22] => Array
(
[length] => 936032
[path] => Array
(
[0] => 100_0829.JPG
)
)
[23] => Array
(
[length] => 963268
[path] => Array
(
[0] => 100_0830.JPG
)
)
[24] => Array
(
[length] => 962300
[path] => Array
(
[0] => 100_0831.JPG
)
)
[25] => Array
(
[length] => 935208
[path] => Array
(
[0] => 100_0832.JPG
)
)
[26] => Array
(
[length] => 908672
[path] => Array
(
[0] => 100_0833.JPG
)
)
[27] => Array
(
[length] => 366944
[path] => Array
(
[0] => 100_0834.JPG
)
)
[28] => Array
(
[length] => 440992
[path] => Array
(
[0] => 100_0835.JPG
)
)
[29] => Array
(
[length] => 379968
[path] => Array
(
[0] => 100_0836.JPG
)
)
[30] => Array
(
[length] => 390580
[path] => Array
(
[0] => 100_0837.JPG
)
)
[31] => Array
(
[length] => 415060
[path] => Array
(
[0] => 100_0838.JPG
)
)
[32] => Array
(
[length] => 370880
[path] => Array
(
[0] => 100_0839.JPG
)
)
[33] => Array
(
[length] => 452056
[path] => Array
(
[0] => 100_0840.JPG
)
)
[34] => Array
(
[length] => 288100
[path] => Array
(
[0] => 100_0841.JPG
)
)
[35] => Array
(
[length] => 458384
[path] => Array
(
[0] => 100_0842.JPG
)
)
[36] => Array
(
[length] => 455640
[path] => Array
(
[0] => 100_0843.JPG
)
)
)
[name] => DC
[piece length] => 65536
[pieces] => [really long string here]
[private] => 1
)
)
I'm intrigued by torrents (im late catching on, i know