PageRenderTime 36ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/TBDev/installer_v4_1/include/benc.php

https://github.com/cybernet/CyBerFuN-CoDeX
PHP | 261 lines | 134 code | 10 blank | 117 comment | 36 complexity | d82cb0a4475c1ca4a02ccd6b7213e5cd MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. ini_set("memory_limit","32M");
  3. /*
  4. Basic knowledge of how bencoding works is assumed. Details can be found
  5. at <http://bitconjurer.org/BitTorrent/protocol.html>.
  6. How to use these functions:
  7. An "object" is defined to be an associative array with at least the keys
  8. "type" and "value" present. The "type" key contains a string which is
  9. one of "string", "integer", "list" or "dictionary". The "value" key
  10. contains the appropriate thing, either a string, an integer, a list which
  11. is just a flat array, or a dictionary, which is an associative array. In
  12. the case of "list" and "dictionary", the values of the contained array
  13. are agaib "objects".
  14. Description of the functions:
  15. string benc($obj);
  16. Takes an object as argument and returns the bencoded form of it as string.
  17. Returns the undefined/unset value on failure.
  18. Examples:
  19. benc(array(type => "string", value => "spam")) returns "4:spam".
  20. benc(array(type => "integer", value => 3)) returns "i3e".
  21. benc(array(type => "list", value => array(
  22. array(type => "string", value => "spam"),
  23. array(type => "string", value => "eggs")
  24. )))
  25. returns "l4:spam4:eggse"
  26. benc(array(type => "dictionary", value => array(
  27. cow => array(type => "string", value => "moo"),
  28. spam => array(type => "string", value => "eggs"),
  29. )))
  30. returns "d3:cow3:moo4:spam4:eggse"
  31. object bdec($str);
  32. Returns the object that results from bdecoding the given string. Note
  33. that those aren't real php objects, but merely "objects" as described
  34. above. The returned objects have two additional keys: "string" and
  35. "strlen". They represent the bencoded form of the returned objects, as
  36. it was given in the original bencoded string. Use this to extract
  37. certain portions of a bencoded string without having to re-encode it
  38. (and avoiding possible re-ordering of dictionary keys). $x["strlen"]
  39. is always equivalent to strlen($x["string"]). The "string" attribute
  40. of the top-level returned object will be the same as the original
  41. bencoded string, unless there's trailing garbage at the end of the
  42. string.
  43. This function returns the undefined/unset value on failure.
  44. Example:
  45. bdec("d4:spaml11:spiced pork3:hamee")
  46. returns this monster:
  47. Array
  48. (
  49. [type] => dictionary
  50. [value] => Array
  51. (
  52. [spam] => Array
  53. (
  54. [type] => list
  55. [value] => Array
  56. (
  57. [0] => Array
  58. (
  59. [type] => string
  60. [value] => spiced pork
  61. [strlen] => 14
  62. [string] => 11:spiced pork
  63. )
  64. [1] => Array
  65. (
  66. [type] => string
  67. [value] => ham
  68. [strlen] => 5
  69. [string] => 3:ham
  70. )
  71. )
  72. [strlen] => 21
  73. [string] => l11:spiced pork3:hame
  74. )
  75. )
  76. [strlen] => 29
  77. [string] => d4:spaml11:spiced pork3:hamee
  78. )
  79. object bdec_file($filename, $maxsize);
  80. Opens the specified file, reads its contents (up to the specified length),
  81. and returns whatever bdec() returns for those contents. This is a simple
  82. convenience function.
  83. */
  84. function benc($obj) {
  85. if (!is_array($obj) || !isset($obj["type"]) || !isset($obj["value"]))
  86. return;
  87. $c = $obj["value"];
  88. switch ($obj["type"]) {
  89. case "string":
  90. return benc_str($c);
  91. case "integer":
  92. return benc_int($c);
  93. case "list":
  94. return benc_list($c);
  95. case "dictionary":
  96. return benc_dict($c);
  97. default:
  98. return;
  99. }
  100. }
  101. function benc_str($s) {
  102. return strlen($s) . ":$s";
  103. }
  104. function benc_int($i) {
  105. return "i" . $i . "e";
  106. }
  107. function benc_list($a) {
  108. $s = "l";
  109. foreach ($a as $e) {
  110. $s .= benc($e);
  111. }
  112. $s .= "e";
  113. return $s;
  114. }
  115. function benc_dict($d) {
  116. $s = "d";
  117. $keys = array_keys($d);
  118. sort($keys);
  119. foreach ($keys as $k) {
  120. $v = $d[$k];
  121. $s .= benc_str($k);
  122. $s .= benc($v);
  123. }
  124. $s .= "e";
  125. return $s;
  126. }
  127. function bdec_file($f, $ms) {
  128. $fp = fopen($f, "rb");
  129. if (!$fp)
  130. return;
  131. $e = fread($fp, $ms);
  132. fclose($fp);
  133. return bdec($e);
  134. }
  135. function bdec($s) {
  136. if (preg_match('/^(\d+):/', $s, $m)) {
  137. $l = $m[1];
  138. $pl = strlen($l) + 1;
  139. $v = substr($s, $pl, $l);
  140. $ss = substr($s, 0, $pl + $l);
  141. if (strlen($v) != $l)
  142. return;
  143. return array("type" => "string", "value" => $v, "strlen" => strlen($ss), "string" => $ss);
  144. }
  145. if (preg_match('/^i(\d+)e/', $s, $m)) {
  146. $v = $m[1];
  147. $ss = "i" . $v . "e";
  148. if ($v === "-0")
  149. return;
  150. if ($v[0] == "0" && strlen($v) != 1)
  151. return;
  152. return array("type" => "integer", "value" => $v, "strlen" => strlen($ss), "string" => $ss);
  153. }
  154. switch ($s[0]) {
  155. case "l":
  156. return bdec_list($s);
  157. case "d":
  158. return bdec_dict($s);
  159. default:
  160. return;
  161. }
  162. }
  163. function bdec_list($s) {
  164. if ($s[0] != "l")
  165. return;
  166. $sl = strlen($s);
  167. $i = 1;
  168. $v = array();
  169. $ss = "l";
  170. for (;;) {
  171. if ($i >= $sl)
  172. return;
  173. if ($s[$i] == "e")
  174. break;
  175. $ret = bdec(substr($s, $i));
  176. if (!isset($ret) || !is_array($ret))
  177. return;
  178. $v[] = $ret;
  179. $i += $ret["strlen"];
  180. $ss .= $ret["string"];
  181. }
  182. $ss .= "e";
  183. return array("type" => "list", "value" => $v, "strlen" => strlen($ss), "string" => $ss);
  184. }
  185. function bdec_dict($s) {
  186. if ($s[0] != "d")
  187. return;
  188. $sl = strlen($s);
  189. $i = 1;
  190. $v = array();
  191. $ss = "d";
  192. for (;;) {
  193. if ($i >= $sl)
  194. return;
  195. if ($s[$i] == "e")
  196. break;
  197. $ret = bdec(substr($s, $i));
  198. if (!isset($ret) || !is_array($ret) || $ret["type"] != "string")
  199. return;
  200. $k = $ret["value"];
  201. $i += $ret["strlen"];
  202. $ss .= $ret["string"];
  203. if ($i >= $sl)
  204. return;
  205. $ret = bdec(substr($s, $i));
  206. if (!isset($ret) || !is_array($ret))
  207. return;
  208. $v[$k] = $ret;
  209. $i += $ret["strlen"];
  210. $ss .= $ret["string"];
  211. }
  212. $ss .= "e";
  213. return array("type" => "dictionary", "value" => $v, "strlen" => strlen($ss), "string" => $ss);
  214. }
  215. ?>