Advertisement
Guest User

Bencode

a guest
Jun 29th, 2011
771
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 2.95 KB | None | 0 0
  1. <?php
  2.  
  3. /*
  4.     http://wiki.theory.org/Decoding_encoding_bencoded_data_with_PHP
  5. */
  6.  
  7. class BencodeModel
  8. {
  9.     function decode_file($filename){
  10.         $string = file_get_contents($filename, FILE_BINARY);
  11.         return $this->decode($string);
  12.     }
  13.  
  14.     function decode($s, &$pos=0)
  15.     {
  16.         if($pos>=strlen($s)) return null;
  17.  
  18.         switch($s[$pos]){
  19.             case 'd':
  20.                 $pos++;
  21.                 $retval = array();
  22.                 while ($s[$pos] != 'e'){
  23.                     $key = $this->decode($s, $pos);
  24.                     $val = $this->decode($s, $pos);
  25.                     if ($key === null || $val === null) break;
  26.                     $retval[$key]=$val;
  27.                 }
  28.                 $retval['isDct'] = True;
  29.                 $pos++;
  30.                 return $retval;
  31.  
  32.             case 'l':
  33.                 $pos++;
  34.                 $retval = array();
  35.                 while ($s[$pos] != 'e'){
  36.                     $val = $this->decode($s, $pos);
  37.                     if ($val === null) break;
  38.                     $retval[]=$val;
  39.                 }
  40.                 $pos++;
  41.                 return $retval;
  42.  
  43.             case 'i':
  44.                 $pos++;
  45.                 $digits = strpos($s, 'e', $pos)-$pos;
  46.                 $val = (int)substr($s, $pos, $digits);
  47.                 $pos += $digits+1;
  48.                 return $val;
  49.  
  50.             default:
  51.                 $digits = strpos($s, ':', $pos)-$pos;
  52.                 if ($digits<0 || $digits >20) return null;
  53.                 $len = (int)substr($s, $pos, $digits);
  54.                 $pos += $digits+1;
  55.                 $str = substr($s, $pos, $len);
  56.                 $pos += $len;
  57.  
  58.                 return (string)$str;
  59.         }
  60.  
  61.         return null;
  62.     }
  63.  
  64.     function encode(&$d){
  65.         $isDict = 0;
  66.         if(is_array($d)){
  67.             $ret = 'l';
  68.             if(isset($d['isDct']) && $d['isDct']){
  69.                 $isDict = 1;
  70.                 $ret = 'd';
  71.  
  72.                 // this is required by the specs, and BitTornado actualy chokes on unsorted dictionaries
  73.                 ksort($d, SORT_STRING);
  74.             }
  75.             foreach($d as $key=>$value) {
  76.                 if($isDict){
  77.                     // skip the isDct element, only if it's set by us
  78.                     if($key == 'isDct' and is_bool($value)) continue;
  79.                     $ret .= strlen($key).':'.$key;
  80.                 }
  81.                 if (is_string($value)) {
  82.                     $ret .= strlen($value).':'.$value;
  83.                 } elseif (is_int($value)){
  84.                     $ret .= "i${value}e";
  85.                 } else {
  86.                     $ret .= $this->encode($value);
  87.                 }
  88.             }
  89.             return $ret.'e';
  90.         } elseif (is_string($d)) // fallback if we're given a single bencoded string or int
  91.             return strlen($d).':'.$d;
  92.         elseif (is_int($d))
  93.             return "i${d}e";
  94.         else
  95.             return null;
  96.     }
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement