Наиболее быстрый и простой парсер (бб-декодер) торрентов |
Здравствуйте, гость ( Вход | Регистрация )
Наиболее быстрый и простой парсер (бб-декодер) торрентов |
4.4.2009, 1:02
Сообщение
#1
|
|
Активный участник Группа: Пользователи Сообщений: 37 Регистрация: 18.1.2009 Пользователь №: 281 |
Задача: обработать на PHP полученный торрент-файл и выловить оттуда:
1) инфо-хеш, 2) дату создания, 3) список треккеров, 4) дерево файлов, если таковое имеется. Для этой цели было найдено несколько исходных кодов: треккер FTS_1_0_1_BETA CODE function bdec($s) { if (preg_match('/^(\d+):/', $s, $m)) { $pl = strlen($m[1]) + 1; $v = substr($s, $pl, $m[1]); $ss = substr($s, 0, $pl + $m[1]); if (strlen($v) != $m[1]) 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); } PHP Classes / BDecode - bdecode_2006_10_28.zip ( 2.45 килобайт ) Кол-во скачиваний: 49 И немного похожий, взятый из TorrentParse v2.2 CODE class BDecode { function numberdecode($wholefile, $start) { $ret[0] = 0; $offset = $start; // Funky handling of negative numbers and zero $negative = false; if ($wholefile[$offset] == '-') { $negative = true; $offset++; } if ($wholefile[$offset] == '0') { $offset++; if ($negative) return array(false); if ($wholefile[$offset] == ':' || $wholefile[$offset] == 'e') { $offset++; $ret[0] = 0; $ret[1] = $offset; return $ret; } return array(false); } while (true) { if ($wholefile[$offset] >= '0' && $wholefile[$offset] <= '9') { $ret[0] *= 10; $ret[0] += ord($wholefile[$offset]) - ord("0"); $offset++; } // Tolerate : or e because this is a multiuse function else if ($wholefile[$offset] == 'e' || $wholefile[$offset] == ':') { $ret[1] = $offset+1; if ($negative) { if ($ret[0] == 0) return array(false); $ret[0] = - $ret[0]; } return $ret; } else return array(false); } } function decodeEntry($wholefile, $offset=0) { if ($wholefile[$offset] == 'd') return $this->decodeDict($wholefile, $offset); if ($wholefile[$offset] == 'l') return $this->decodelist($wholefile, $offset); if ($wholefile[$offset] == "i") { $offset++; return $this->numberdecode($wholefile, $offset); } // String value: decode number, then grab substring $info = $this->numberdecode($wholefile, $offset); if ($info[0] === false) return array(false); $ret[0] = substr($wholefile, $info[1], $info[0]); $ret[1] = $info[1]+strlen($ret[0]); return $ret; } function decodeList($wholefile, $start) { $offset = $start+1; $i = 0; if ($wholefile[$start] != 'l') return array(false); $ret = array(); while (true) { if ($wholefile[$offset] == 'e') break; $value = $this->decodeEntry($wholefile, $offset); if ($value[0] === false) return array(false); $ret[$i] = $value[0]; $offset = $value[1]; $i ++; } // The empy list is an empty array. Seems fine. $final[0] = $ret; $final[1] = $offset+1; return $final; } // Tries to construct an array function decodeDict($wholefile, $start=0) { $offset = $start; if ($wholefile[$offset] == 'l') return $this->decodeList($wholefile, $start); if ($wholefile[$offset] != 'd') return false; $ret = array(); $offset++; while (true) { if ($wholefile[$offset] == 'e') { $offset++; break; } $left = $this->decodeEntry($wholefile, $offset); if (!$left[0]) return false; $offset = $left[1]; if ($wholefile[$offset] == 'd') { // Recurse $value = $this->decodedict($wholefile, $offset); if (!$value[0]) return false; $ret[addslashes($left[0])] = $value[0]; $offset= $value[1]; continue; } else if ($wholefile[$offset] == 'l') { $value = $this->decodeList($wholefile, $offset); if (!$value[0] && is_bool($value[0])) return false; $ret[addslashes($left[0])] = $value[0]; $offset = $value[1]; } else { $value = $this->decodeEntry($wholefile, $offset); if ($value[0] === false) return false; $ret[addslashes($left[0])] = $value[0]; $offset = $value[1]; } } if (empty($ret)) $final[0] = true; else $final[0] = $ret; $final[1] = $offset; return $final; } } // End of class declaration. // Use this function. eg: BDecode("d8:announce44:http://www. ... e"); function BDecode($wholefile) { $decoder = new BDecode; $return = $decoder->decodeEntry($wholefile); return $return[0]; } Все 3 варианта почему-то не парсят торренты, либо при работе превышают 20 метров выделяемой памяти. Помогите, кто чем может. Заранее благодарен.
Прикрепленные файлы
|
|
|
4.4.2009, 10:32
Сообщение
#2
|
|
Активный участник Группа: Главные Админы Сообщений: 661 Регистрация: 15.12.2008 Из: Москва Пользователь №: 15 |
Используйте http://pear.php.net/package/File_Bittorrent2 и не изобретайте велосипед.
-------------------- |
|
|
5.4.2009, 1:02
Сообщение
#3
|
|
Активный участник Группа: Пользователи Сообщений: 37 Регистрация: 18.1.2009 Пользователь №: 281 |
FreeM@N, спасибо, а можно что-нть без PEAR?
|
|
|
5.4.2009, 12:47
Сообщение
#4
|
|
Активный участник Группа: Главные Админы Сообщений: 661 Регистрация: 15.12.2008 Из: Москва Пользователь №: 15 |
FreeM@N, спасибо, а можно что-нть без PEAR? Убираете из кода привязку к PEAR и получаете тоже самое, но без PEAR. -------------------- |
|
|
7.4.2009, 10:02
Сообщение
#5
|
|
Активный участник Группа: Пользователи Сообщений: 37 Регистрация: 18.1.2009 Пользователь №: 281 |
Глюк был в следующем: при вызове file_get_contents(), добавлялись слеши - подправил, добавив stripslashes()
|
|
|
Текстовая версия | Сейчас: 1.11.2024, 2:09 |