|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
lightbenc.php:PHP解析torrent内容类
lightbenc.php:- <?php
- /* lightbenc.php
- Dear Bram Cohen,
- You are an arse
- WHAT were you smoking ?
- This implementation should use one order of magnitude less memory then the TBdev version.
- The bdecoding speed is similar to TBdev, bencoding is faster, and much faster then bdecoding.
- Call the bdecode() function with the bencoded string:
- $str="d7:oneListl8:a stringe10:oneIntegeri34ee";
- var_dump(bdecode($str));
- array(3) {
- ["oneList"]=>
- array(1) {
- [0]=>
- string(8) "a string"
- }
- ["oneInteger"]=>
- int(34)
- ["isDct"]=>
- bool(true)
- }
- The returned value is a nested data type with the following type of elements:
- - ints (test type with is_integer($x))
- - strings (test type with is_string($x))
- - lists (test type with is_array($x) && !isset($x[isDct])
- - dicts (test type with is_array($x) && isset($x[isDct])
- All elements have the native PHP type, except for the dictionary which is an array with an "isDct" key.
- This is necessary since PHP makes no distinction between flat and associative arrays. Note that the isDct
- key is allways set as a bool, so that even if the dictionary contains an actual "isDct" value, the
- functions behave transparently, i.e. they don't strip out or overwrite actual "isDct" keys.
- As such, this implementation is not a drop-in replacement of the TBDev code, hence the new function names
- For all practical purposes, it's just as flexible, and very easy to use. For example:
- // decode the torrent file
- $dict= bdecode_file($torrentfilename);
- // change announce url
- $dict['announce']='http://inferno.demonoid.com';
- // add private tracker flag
- $dict['info']['private']=1;
- // compute infohash
- $infohash = pack("H*", sha1(bencode($dict["info"])));
- // recreate the torrent file
- $torrentfile=bencode($dict);
- After calling bencode(), the passed nested array will have all it's dictionaries sorted by key.
- The bencoded data generated by bencode() will have sorted dictionaries, but bdecode() does not require
- this in the input stream, and will keep the order unchanged.
- This implementation is hereby released under the GFYPL, version 1.00.
- The Go Fuck Yourself Public License, version 1.00
- Article 1
- You can go fuck yourself.
- END OF ALL TERMS AND CONDITIONS
- */
- class Lightbenc{
- public static function bdecode($s, &$pos=0) {
- if($pos>=strlen($s)) {
- return null;
- }
- switch($s[$pos]){
- case 'd':
- $pos++;
- $retval=array();
- while ($s[$pos]!='e'){
- $key=Lightbenc::bdecode($s, $pos);
- $val=Lightbenc::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=Lightbenc::bdecode($s, $pos);
- if ($val===null)
- break;
- $retval[]=$val;
- }
- $pos++;
- return $retval;
- case 'i':
- $pos++;
- $digits=strpos($s, 'e', $pos)-$pos;
- $val=(int)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;
- }
- public static function bencode(&$d){
- if(is_array($d)){
- $ret="l";
- if(isset($d["isDct"])&&$d["isDct"]){
- $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(isset($isDict)&&$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_string($value)) {
- $ret.=strlen($value).":".$value;
- } elseif (is_int($value)){
- $ret.="i${value}e";
- } else {
- $ret.=Lightbenc::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))
- return "i${d}e";
- else
- return null;
- }
- public static function bdecode_file($filename){
- $f=file_get_contents($filename, FILE_BINARY);
- return Lightbenc::bdecode($f);
- }
- public static function bdecode_getinfo($filename){
- $t = Lightbenc::bdecode(file_get_contents($filename, FILE_BINARY));
- $t['info_hash'] = sha1(Lightbenc::bencode($t['info']));
- if(is_array($t['info']['files'])){ //multifile
- $t['info']['size'] = 0;
- $t['info']['filecount'] = 0;
- foreach($t['info']['files'] as $file){
- $t['info']['filecount']++;
- $t['info']['size']+=$file['length'];
- }
- }else{
- $t['info']['size'] = $t['info']['length'];
- $t['info']["filecount"] = 1;
- $t['info']['files'][0]['path'] = $t['info']['name'];
- $t['info']['files'][0]['length'] = $t['info']['length'];
- }
- return $t;
- }
- }
- ?>
复制代码
使用方法:
引入lightbenc.php文件
构建实例- $Lightbenc = new Lightbenc();
复制代码
解析bt文件- $file_info = $Lightbenc->bdecode_getinfo(‘ed01289e3f9d660fa1f60b79c13fb4eec8901498.torrent’);
复制代码
$file_info 就是我们获取到的bt文件的信息,里面包含了bt文件的服务器地址,文件个数和文件大小等信息,其中:
文件名称:$bt[‘info’][‘files’][/*这边要是个偶数*/][‘path.utf-8′][0];
文件大小:$bt[‘info’][‘files’][/*这边要是个偶数*/][‘path.utf-8′][0];
如果要输出GBK的编码就把上面代码里面的’path.utf-8’换成’path’就可以了
杂记
- include "lightbenc.php";
- $file="1.torrent";//BT文件名
- $btinfo = Lightbenc::BDecode($file);//解析BT文件信息,放入$btinfo数组
- $infohash = Lightbenc::bdecode_getinfo($file);//解析BT文件hash值,并放入$infohash数组
- //可以用以下函数获取以上所有数组信息
- echo var_dump(Lightbenc::bdecode($file));
- echo var_dump(Lightbenc::bdecode_getinfo($file));
- //下面是我总结的一些
- echo $btinfo['info']['name'];//获取种子文件名
- echo $btinfo['announce'][/*从0开始,一个数对应一个服务器*/];//读取Tracker服务器列表
- echo $btinfo['info']['files'][/*从0开始,一个数对应一个文件*/]['path']['0'];//读取BT文件名称,多个文件的替换中间的数字
- echo $btinfo['info']['files'][/*从0开始,一个数对应一个文件*/]['length'];//读取BT文件单个文件大小
- echo $infohash['info_hash'];//获取BT文件hash值
复制代码 |
|