最新消息:

python实现bt种子转磁链接之——bt种子解析即协议分析(二)

Python 大步 2671浏览 0评论

接上面一篇:python实现bt种子转磁链接之——bt种子解析即协议分析(一)

BT 协议中的种子文件介绍
.torrent 文件编码格式
.torrent 文件的编码格式为B 编码,是一种简洁的数据组织方式,支持4 种数据类型:
byte strings、integers、lists 和dictionaries,它们各自的表示方式见表1。7.torrent 文件格式

图 2 展现了一个.torrent 文件的内容:

0301

其中的一些主要域如下:
◆announce:tracker 服务器的URL,本例中为http//tracker.cnxp.com:8080/announce。
◆announce-list(可选):。备用tracker 服务器的URL 列表,本例中为http://tracker.cnxp.com:8080/announce、http://btfans.3322.org:6969/announce 等。
◆creation date(可选):.torrent 文件的创建日期,使用标准的UNIX 时间,本例中为
1152105243。
◆comment(可选):.torrent 文件制作者添加的任意格式的说明。
◆created by(可选):制作.torrent 文件的工具,本例中使用的制作工具是BitComet/0.67。
◆encoding(可选):发布的资源使用的编码方式,在本例中使用的是GBK。
◆info:发布的文件的信息。有两种格式,单文件格式和多文件格式。
单文件格式包括 length、md5sum(可选)、name、piece length、pieces;多文件格式包括files、name、piece length、pieces,其中files 包括length、path、md5sum(可选),每一个文件都有单独的length、path、md5sum(可选)。本例使用多文件格式,共有两个 文件,分别是“Love Undercover Ⅲ.txt”和“影视帝国(bbs.cnxp.com).新扎师妹3.国语DVDSCR 中字.rmvb”,piece 长度为262144byte,piece 个数为34780

libtorrent 的种子文件解析方法

libtorrent 是用C++为*nix 用户写的BitTorrent 库。libtorrent 用到了很多C++的模板库(主要是boost),客户端的性能非常好,而且还提供库函数给其它程序调用。协议库libtorrent 源码包的src/torrent 文件夹中,文件object.cc 和object.h 设计了类Object。该类中定义了一种数据结构用以存放B 编码的字符流。因为类的定义中用到了string 类和标准模板库STL,所以包含头文件<string>、<map>和<list>。

类Object 介绍

2013-04-06_151110

表2 和表3 列出了类Object 自定义的类型和成员变量。
类 Object 中的成员函数,按功能可分为两类:
◆查询类函数
◇根据对象的 m_type 用以判断对象的类型:
is_value()
is_string()
is_list()
is_map()

◇指示m_map 指向的map<string,Object>中是否有键值为k 且域类型为TYPE_VALUE、
TYPE_STRING、TYPE_LIST、TYPE_MAP 的元素:
has_key_value(key_type& k)
has_key_string(key_type& k)
has_key_list(key_type& k)
has_key_map(key_type& k)
◇获取m_map 指向的map<string,Object>中键值为k 的元素的域值(类Object 的对象):
get_key_value(key_type& k)获取键值为k 的域值的m_value
get_key_string(key_type& k)获取键值为k 的域值的m_string 指向的string
get_key_list(key_type& k)获取键值为k 的域值的m_list 指向的list<Object>
get_key_map(key_type& k)获取键值为k 的域值的m_map 指向的map<string,Object>
◆操作类函数
insert_key(key_type& k, Object& b)向m_map 指向的map<string, Object>中插入一个键值为k、域值为b 的元素。
erase_key(key_type& k)删除m_map 指向的map<string, Object>中键值为k 的元素。
insert_front(Object& b)在m_list 指向的list<Object>的第一个元素前插入元素b。
insert_back(Object& b)在m_list 指向的list<Object>的最后一个元素后插入元素b。
move(Object& src)将src 赋值给当前对象。
swap(Object& src)将当前对象与src 进行值的交换。

种子文件解析过程
libtorrent 源码包的src/torrent 文件夹中, 文件object_stream.cc 定义了函数object_read_string()和object_read_bencode(),它们对通过instream 流读取到的B 编码的字符串流进行解析。

首先介绍一下读取 B 编码的字符串格式的函数,其声明如下:
bool object_read_string ( std::istream* input, std::string& str )
由上文知,B 编码的字符串格式为:<十进制ASCII 表示的字符串长度>:<字符串数>。据>。

例如,4:spam 表示字符串spam。
函数的实现如下:首先*input>>size 读入长度,将读入的整型值存入size 变量中。然后,用input->get()读入分隔符‘:’。将str 的大小初始化为size,接下来用input->get()读入size个字符串,存入str 中,这期间需要关注input 的failbit 是否被置1。
下面再来看一下读取 B 编码格式的函数,其声明如下:
void object_read_bencode ( std::istream* input, Object* object, uint32_t depth = 0 )
参数depth 用以表示函数的嵌套深度。在声明时,提供的默认参数值为0。函数中设定
的嵌套深度的上限为1024。
函数的实现如下:
用 input->peek()获取输入流的第一字符赋给整型变量c,对c 使用case 分支语句。
(1)若c 为‘i’,则表示为“整数”的编码格式。
创建一个 m_type 为TYPE_VALUE 的类Object 的对象并将其赋给object。再读入‘i’字符后的数字并将其赋给object 的m_value。当读到字符‘e’时,函数返回。
(2)若c 为‘l’,则表示为“列表”的编码格式。
创建一个 m_type 为TYPE_LIST 的类Object 的对象并将其赋给object。在object 的m_list指向的list<Object>中插入一个m_type 为TYPE_NONE 的类Object 的对象。再嵌套调用本函数,传入参数依次为input、之前插入的类Object 的对象的地址以及depth。当读到字符‘e’时,函数返回。
(3)若c 为‘d’,则表示为“字典”的编码格式。
创建一个 m_type 为TYPE_MAP 的类Object 的对象并将其赋给object。因为“字典”
的编码形式中每个项的键值都是一个B 编码的字符串类型,所以首先调用之前定义的函数object_read_string 读取字符‘d’后的B 编码的字符串类型的,从中提取的字符串赋给
Object::string_type 类型的str。再嵌套调用本函数,传入的三个参数依次为input、object 中的m_map 指向的map<string,Object>中键值为str 的域值的地址、depth。当读到字符‘e’时,函数返回。
(4)若c 为‘0’到‘9’之间的字符,则表示为“字符串”的编码格式。
创建一个 m_type 为TYPE_STRING 的类Object 的对象并将其赋给object。调用之前定
义的函数object_read_string,传入的两个参数为input 和object 的m_string 所指向的string类型值。

###############################

python实现bt种子转磁链接之——bt种子解析即协议分析(完),接下来是:

python实现bt种子转磁链接之——磁链接的分析

转载请注明:大步's Blog » python实现bt种子转磁链接之——bt种子解析即协议分析(二)

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
SiteMap