Skip to content
This repository has been archived by the owner on Oct 26, 2019. It is now read-only.

Commit

Permalink
Version 1.0 final commit
Browse files Browse the repository at this point in the history
Version 1.0 final commit
  • Loading branch information
Abi Narayan committed Sep 24, 2013
1 parent 667dfe6 commit bf44b98
Showing 1 changed file with 244 additions and 0 deletions.
244 changes: 244 additions & 0 deletions src/Bhutanio/BEncode/Bencode.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,253 @@
* A BEncode Wrapper for Laravel
* Original src - https://wiki.theory.org/Decoding_encoding_bencoded_data_with_PHP
*
* GIT :: https://github.com/bhutanio/laravel-bencode
*
* @package laravel-bencode
* @author Abi Xalmon
*/
class BENCODE {

//public $announce = 'http://abi.io/announce';
public $announce = null;
// Torrent Comment
public $comment = null;
// Created by Program
public $created_by = null;

function __construct() {
// Here you can load default announce URL, comment and created_by from your configuration file.
}

// Set torrent data
/**
* Data Setter
* @param array $data [array of public variables]
* eg:
*
* BENCODE::set([
* 'announce'=>'http://www.torrentsite.com',
* 'comment'=>'Downloaded from torrentsite.com',
* 'created_by'=>'TorrentSite v1.0'
* ]);
*/
public function set($data=array())
{
if ( is_array($data) ) {
foreach ($data as $key => $value) {
$this->$key = $value;
}
}
}

/**
* Decode a torrent file into Bencoded data
* @param string $s [link to torrent file]
* @param integer $pos [file position pointer]
* @return array/null [Array of Bencoded data]
* eg:
* $torrent = BENCODE::bdecode( File::get('MyMovieTorrent.torrent'));
* var_dump($torrent);
*/
public function bdecode($s, &$pos=0)
{
if($pos>=strlen($s)) {
return null;
}
switch($s[$pos]){
case 'd':
$pos++;
$retval=array();
while ($s[$pos]!='e'){
$key=BENCODE::bdecode($s, $pos);
$val=BENCODE::bdecode($s, $pos);
if ($key===null || $val===null)
break;
$retval[$key]=$val;
}
$retval["isDct"]=true;
$pos++;
return $retval;

case 'l':
$pos++;
$retval=array();
while ($s[$pos]!='e'){
$val=BENCODE::bdecode($s, $pos);
if ($val===null)
break;
$retval[]=$val;
}
$pos++;
return $retval;

case 'i':
$pos++;
$digits=strpos($s, 'e', $pos)-$pos;
$val=round((float)substr($s, $pos, $digits));
$pos+=$digits+1;
return $val;

// case "0": case "1": case "2": case "3": case "4":
// case "5": case "6": case "7": case "8": case "9":
default:
$digits=strpos($s, ':', $pos)-$pos;
if ($digits<0 || $digits >20)
return null;
$len=(int)substr($s, $pos, $digits);
$pos+=$digits+1;
$str=substr($s, $pos, $len);
$pos+=$len;
//echo "pos: $pos str: [$str] len: $len digits: $digits\n";
return (string)$str;
}
return null;
}

/**
* Created Torrent file from Bencoded data
* @param array $d [array data of a decoded torrent file]
* @return string [data can be downloaded as torrent]
*/
public function bencode(&$d)
{
if(is_array($d)){
$ret="l";
$isDict = false;
if( isset($d["isDct"]) && $d["isDct"]===true ){
$isDict=1;
$ret="d";
// this is required by the specs, and BitTornado actualy chokes on unsorted dictionaries
ksort($d, SORT_STRING);
}
foreach($d as $key=>$value) {
if($isDict){
// skip the isDct element, only if it's set by us
if($key=="isDct" and is_bool($value)) continue;
$ret.=strlen($key).":".$key;
}
if (is_int($value) || is_float($value)){
$ret.="i${value}e";
}else if (is_string($value)) {
$ret.=strlen($value).":".$value;
} else {
$ret.=BENCODE::bencode ($value);
}
}
return $ret."e";
} elseif (is_string($d)) // fallback if we're given a single bencoded string or int
return strlen($d).":".$d;
elseif (is_int($d) || is_float($d))
return "i${d}e";
else
return null;
}

/**
* Decode a torrent file into Bencoded data
* @param string $filename [File Path]
* @return array/null [Array of Bencoded data]
*/
public function bdecode_file($filename)
{
if ( is_file($filename) ) {
$f=file_get_contents($filename, FILE_BINARY);
return BENCODE::bdecode($f);
}
return null;
}

/**
* Generate list of files in a torrent
* @param array $data [array data of a decoded torrent file]
* @return array [list of files in an array]
*/
public function filelist($data)
{
$FileCount = 0;
$FileList = array();
if(!isset($data['info']['files']) ) // Single file mode
{
$FileCount = 1;
$TotalSize = $data['info']['length'];
$FileList[]= array($data['info']['length'], $data['info']['name']);
} else { // Multiple file mode
$FileNames = array();
$TotalSize = 0;
$Files = $data['info']['files'];
foreach($Files as $File) {
$FileCount++;
$TotalSize+=$File['length'];
$FileSize = $File['length'];

$FileName = ltrim(implode('/',$File['path']), '/');

$FileList[] = array('size'=>$FileSize, 'name'=>$FileName);
$FileNames[] = $FileName;
}
array_multisort($FileNames, $FileList);
}
return array('file_count'=>$FileCount, 'total_size'=>$TotalSize, 'files'=>$FileList);
}

/**
* Replace array data on Decoded torrent data so that it can be bencoded into a private torrent file.
* Provide the custom data using BENCODE::set();
* @param array $data [array data of a decoded torrent file]
* @return array [array data for torrent file]
*/
public function make_private($data)
{
// Remove announce
// announce-list is an unofficial extension to the protocol
// that allows for multiple trackers per torrent
unset($data['announce']);
unset($data['announce-list']);

// Bitcomet & Azureus cache peers in here
unset($data['nodes']);

// Azureus stores the dht_backup_enable flag here
unset($data['azureus_properties']);

// Remove web-seeds
unset($data['url-list']);

// Remove libtorrent resume info
unset($data['libtorrent_resume']);

// Remove profiles / Media Infos
unset($data['info']['profiles']);
unset($data['info']['file-duration']);
unset($data['info']['file-media']);

// Add Announce URL
if ( is_array($this->announce) ) {
$data['announce'] = reset($this->announce);
$data["announce-list"] = array();
$announce_list = array();
foreach ($this->announce as $announceUri) {
$announce_list[] = $announceUri;
}
$data["announce-list"] = $announce_list;
} else {
$data['announce'] = $this->announce;
}

// Add Comment
$data['comment'] = $this->comment;

// Created by and Created on
$data['created by'] = $this->created_by;
$data['creation date'] = time();

// Make Private
$data['info']['private'] = 1;

// Sort by key to respect spec
ksort($data['info']);
ksort($data);

return $data;
}
}

0 comments on commit bf44b98

Please sign in to comment.