/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
- <?php
- ini_set("memory_limit","32M");
- /*
-
- Basic knowledge of how bencoding works is assumed. Details can be found
- at <http://bitconjurer.org/BitTorrent/protocol.html>.
-
-
-
- How to use these functions:
-
- An "object" is defined to be an associative array with at least the keys
- "type" and "value" present. The "type" key contains a string which is
- one of "string", "integer", "list" or "dictionary". The "value" key
- contains the appropriate thing, either a string, an integer, a list which
- is just a flat array, or a dictionary, which is an associative array. In
- the case of "list" and "dictionary", the values of the contained array
- are agaib "objects".
-
-
-
- Description of the functions:
-
-
-
- string benc($obj);
-
- Takes an object as argument and returns the bencoded form of it as string.
- Returns the undefined/unset value on failure.
-
- Examples:
-
- benc(array(type => "string", value => "spam")) returns "4:spam".
- benc(array(type => "integer", value => 3)) returns "i3e".
- benc(array(type => "list", value => array(
- array(type => "string", value => "spam"),
- array(type => "string", value => "eggs")
- )))
- returns "l4:spam4:eggse"
-
- benc(array(type => "dictionary", value => array(
- cow => array(type => "string", value => "moo"),
- spam => array(type => "string", value => "eggs"),
- )))
- returns "d3:cow3:moo4:spam4:eggse"
-
-
-
-
- object bdec($str);
-
- Returns the object that results from bdecoding the given string. Note
- that those aren't real php objects, but merely "objects" as described
- above. The returned objects have two additional keys: "string" and
- "strlen". They represent the bencoded form of the returned objects, as
- it was given in the original bencoded string. Use this to extract
- certain portions of a bencoded string without having to re-encode it
- (and avoiding possible re-ordering of dictionary keys). $x["strlen"]
- is always equivalent to strlen($x["string"]). The "string" attribute
- of the top-level returned object will be the same as the original
- bencoded string, unless there's trailing garbage at the end of the
- string.
-
- This function returns the undefined/unset value on failure.
-
- Example:
-
- bdec("d4:spaml11:spiced pork3:hamee")
- returns this monster:
-
- Array
- (
- [type] => dictionary
- [value] => Array
- (
- [spam] => Array
- (
- [type] => list
- [value] => Array
- (
- [0] => Array
- (
- [type] => string
- [value] => spiced pork
- [strlen] => 14
- [string] => 11:spiced pork
- )
-
- [1] => Array
- (
- [type] => string
- [value] => ham
- [strlen] => 5
- [string] => 3:ham
- )
-
- )
-
- [strlen] => 21
- [string] => l11:spiced pork3:hame
- )
-
- )
-
- [strlen] => 29
- [string] => d4:spaml11:spiced pork3:hamee
- )
-
-
-
-
-
- object bdec_file($filename, $maxsize);
-
- Opens the specified file, reads its contents (up to the specified length),
- and returns whatever bdec() returns for those contents. This is a simple
- convenience function.
-
- */
-
- function benc($obj) {
- if (!is_array($obj) || !isset($obj["type"]) || !isset($obj["value"]))
- return;
- $c = $obj["value"];
- switch ($obj["type"]) {
- case "string":
- return benc_str($c);
- case "integer":
- return benc_int($c);
- case "list":
- return benc_list($c);
- case "dictionary":
- return benc_dict($c);
- default:
- return;
- }
- }
-
- function benc_str($s) {
- return strlen($s) . ":$s";
- }
-
- function benc_int($i) {
- return "i" . $i . "e";
- }
-
- function benc_list($a) {
- $s = "l";
- foreach ($a as $e) {
- $s .= benc($e);
- }
- $s .= "e";
- return $s;
- }
-
- function benc_dict($d) {
- $s = "d";
- $keys = array_keys($d);
- sort($keys);
- foreach ($keys as $k) {
- $v = $d[$k];
- $s .= benc_str($k);
- $s .= benc($v);
- }
- $s .= "e";
- return $s;
- }
-
- function bdec_file($f, $ms) {
- $fp = fopen($f, "rb");
- if (!$fp)
- return;
- $e = fread($fp, $ms);
- fclose($fp);
- return bdec($e);
- }
-
- function bdec($s) {
- if (preg_match('/^(\d+):/', $s, $m)) {
- $l = $m[1];
- $pl = strlen($l) + 1;
- $v = substr($s, $pl, $l);
- $ss = substr($s, 0, $pl + $l);
- if (strlen($v) != $l)
- return;
- return array("type" => "string", "value" => $v, "strlen" => strlen($ss), "string" => $ss);
- }
- if (preg_match('/^i(\d+)e/', $s, $m)) {
- $v = $m[1];
- $ss = "i" . $v . "e";
- if ($v === "-0")
- return;
- if ($v[0] == "0" && strlen($v) != 1)
- return;
- return array("type" => "integer", "value" => $v, "strlen" => strlen($ss), "string" => $ss);
- }
- switch ($s[0]) {
- case "l":
- return bdec_list($s);
- case "d":
- return bdec_dict($s);
- default:
- return;
- }
- }
-
- function bdec_list($s) {
- if ($s[0] != "l")
- return;
- $sl = strlen($s);
- $i = 1;
- $v = array();
- $ss = "l";
- for (;;) {
- if ($i >= $sl)
- return;
- if ($s[$i] == "e")
- break;
- $ret = bdec(substr($s, $i));
- if (!isset($ret) || !is_array($ret))
- return;
- $v[] = $ret;
- $i += $ret["strlen"];
- $ss .= $ret["string"];
- }
- $ss .= "e";
- return array("type" => "list", "value" => $v, "strlen" => strlen($ss), "string" => $ss);
- }
-
- function bdec_dict($s) {
- if ($s[0] != "d")
- return;
- $sl = strlen($s);
- $i = 1;
- $v = array();
- $ss = "d";
- for (;;) {
- if ($i >= $sl)
- return;
- if ($s[$i] == "e")
- break;
- $ret = bdec(substr($s, $i));
- if (!isset($ret) || !is_array($ret) || $ret["type"] != "string")
- return;
- $k = $ret["value"];
- $i += $ret["strlen"];
- $ss .= $ret["string"];
- if ($i >= $sl)
- return;
- $ret = bdec(substr($s, $i));
- if (!isset($ret) || !is_array($ret))
- return;
- $v[$k] = $ret;
- $i += $ret["strlen"];
- $ss .= $ret["string"];
- }
- $ss .= "e";
- return array("type" => "dictionary", "value" => $v, "strlen" => strlen($ss), "string" => $ss);
- }
-
- ?>