. 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); } ?>