Chinaunix首页 | 论坛 | 博客
  • 博客访问: 563458
  • 博文数量: 104
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1559
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-21 00:58
个人简介

锻炼精神,首先要锻炼肉体

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-04-10 11:56:57

如果你了解 点对点传输(P2P)的话,那么你一定了解种子文件,通常我们说的“种子文件”实质上便是 .torrent 文件。
这种文件时点对点传输中必不可少的文件,在这个文件中指定了下载资源的一方
所需要下载的资源所在服务器的 URL 地址、
以及将资源分为多少个piece 进行下载,每个 piece 的大小等等信息。


就像是到从未去过的朋友家玩,朋友为了方便你找到他家的位置,提前将他家的信息写到一张纸上,
你按照纸上所标定的地址去找,便可以正确的找到朋友家的原理一样,.torrent 文件便是这张朋友给你写的纸。

但是,如果朋友在纸上写的信息加上标点的话,那么信息很难以阅读,.torrent 文件也是如此,
数据在网络中传送通常都是按照一定的编码方式进行编码的,不同的字段对应的不同的信息含义。

比如说,分布式数据库之间在互传一张数据表信息的时候,它通常会使用编码手段,来标定需要传送不同的数据,
不然,接收数据的一方并不知道所接受到的数据的具体含义。
比如说下面 xml 代码中所描绘的两个位于不同主机上的数据库进行通信的时候所发送的数据表信息。

(知道大概含义即可,下面的 xml 代码写的并不合法)

点击(此处)折叠或打开

  1. <database-name = "university">
  2.    <table-name = "student">
  3.      <field-namestu_id  </field-name>
  4.       stu_name 
  5.   </table-name>
  6.   
  7.   
  8.       teacher-id  
  9.  
  10. </database-name>

B 编码如同上述的 xml 文档中的编码方式一样,通过预先设定好的不同语义规则来表达不同的信息结构类型。
它的语义简单,规则固定,并且经过B编码之后的数据中冗余信息极少,十分适合作为网络传输数据信息的编码规则。
由于 P2P 中对数据信息的类型要求不多,使用 B 编码来描述端与端之间传输的信息已经足够,所以 B 编码成为了
.torrent 文件与资源推送与下载的端点信息交互必不可少的编码方式。

本文主要介绍 B编码的方式,以及在了解 B 编码之后,分析.torrent 文件与 Tracker 回复信息并从中抽取出有用的信息字段,
最后总结一下在 .torrent 文件和 Tracker 回复信息中必要的信息字段有哪些,并且这些必要的信息字段都是如何编码的 B 编码格式的。

学习这些知识为将来编写一个解析 .torrent 文件的程序打下基础。

1. B编码
  1.1 B 编码中定义的编码格式
        在 B 编码中定义的格式共有 4 中,分别是
        字符类型(strings) , 整数类型(integers) , 列表类型(list) , 字典类型(dictionary)
        
   画图软件使用的是:  

        字符类型(strings): 这种编码格式是四种编码方式中唯一没有前缀和后缀的,
        <字符串长度>:<字符串内容>
        辨认方式:开头为数字的B编码必定是字符串类型 (这里的辨认方式是为我们今后的编程打下基础)
        例子      :12:inuyasha1027(B 编码) <---> inuyasha1027(字符串)


        整型类型(integers):这种编码格式的前缀是 'i' , 后缀是 'e', 其中前缀表示的是 integer , 后缀表示的是 end
        辨认方式: 开头为 i 的B编码必定是整型类型
        例子:    i3216732167e(B 编码) <---> 3216732167(整型数值)
        
        在 B 编码的整型数值编码中有几个需要注意的事项:
        1,编码的整型数值必须是十进制的
        2. 数值 0 的编码为 i0e
        3. i-0e 的编码方式是非法的
        4. i012345e 这种以 0 开头的表示方式也是非法的  


        列表类型(list) : 这种编码方式的前缀是 'l' , 后缀是 'e', 其中前缀的表示是 list , 后缀的含义是 end
        le 的中间可以有任意个数且任意类型的B编码类型,list, integers , dict, strings 都可以,只要其表述合法即可。
       
        辨认方式:以 l 开头的 B 编码必定是列表类型
       
        例子: l4:testl3:inui32167eee(B编码) <---> list<  string (test) , list< string(inu) , integer(32167) > > 
        上述的 B 编码列表中定义了其中包含一个字符串("test")列表(即列表中包含一个列表)里面的这个列表中
        含有一个字符串(“inu”)一个整型数值(3267)
       
        列表类型比较难理解,是因为其中有着关于自己的递归定义,即列表里面可以定义任何类型,即还可以嵌套定义一个列表,
        内列表里面还可以定义各种类型,以此类推,子子孙孙无穷无尽,自行脑补。


        字典类型(dictionary):这种编码方式的前缀是 ‘d’ 后缀是 'e' , 其中前缀的含义是 dictionary ,后缀代表的意思是 end
        从上面的图中可以知道字典的编码方式, <关键字>:<值>
        在这里请注意,关键字一定要是 strings 字符串类型,而值可以是任意类型,但是请注意只能是一个,即关键字<-->
        二者是一一对应的。但是一个字典中可以有不止一对 <关键字>:<值>

        好吧,那么问题来了,如何判断 关键字 后面对应的 值 是什么类型的呢?
        关键字:必定 strings 类型,整型数值:字符串内容:xmmmmmmmmmm,重点就在字符串内容结束之后,开始的第一个 x 上面 

        x 如果是整数----> 值必定是一个字符串 strings 类型
        x 如果是 i     ----> 值必定是一个整型 integers 类型
        x 如果是 l    -----> 值必定是一个列表 list 类型 ,鉴于 list 中可以包含各种类型,需要小心执行分析
        x 如果是 d   -----> 值必定是一个字典 dict 类型,鉴于这里涉及到递归定义,注意分析内嵌 dict 中的内容      
        
        辨认方式: 以 d 开头的B编码必定是字典类型

        例子: d12:inuyasha1027l5:email20inuyasha1027@163.comee (B 编码)
        上述例子中是一个字典,这个字典的关键字是 字符串:"inuyasha1027"
        值是 列表 list , 列表中包含有2 个字符串:
        字符串1(长度5,内容 ”email“)
        字符串2 (长度 20 , 内容 "inuyasha1027@163.com")

2. 分析.torrent 文件
    2.1 .torrent 文件中包含的信息字段有哪些?
    首先,请看一张思维导图
    
    从图中的 .torrent 文件即为 metafile 即元文件,在该文件中包含有如下的信息
   
名称 类型 功能
announce
(重要,必选)
字典类型d>>e 该字段是用来指定下载资源所存放服务器的URL
announce-list
(可选项)
字典类型 d>>e 该字段是用来指定存放同一资源的其他服务器所在的URL
created by
(可选项)
            ///// 生成种子文件的客户端信息
create-date
(可选项)
字典类型 d
create-date
>>e
种子文件的创建时间,从1970/1/1 00:00:00 到当前系统时间的秒数,整型
comment
(可选项)
字典类型 d>>e 该关键字对应的值记录的是该种子文件的描述信息
info
(重要,必选项)
字典类型 d>>e 该关键字对应的值记录是资源在网络中传输的块的大小 piece length,
它值是integers:整型类型,通常数值为 {256K,128K,512K}
即 12:piece length后面跟着{i262144e, i524288e, i131072e}

以及资源是由多少个块组成的 pieces ,它也是一个字典类型,关键字为 piece,
后面的值是一个长度固定为 20 的整数倍才合法的 hash 值,类型为 strings 
6:pieces 20*n:hash-value

info 字段中的 private 字段可以取值 (0,1) 通常情况下都是private= 0 ,
含义是资源所存放的服务器的地址是可以直接获得的,即给定IP:port 信息即可获得

如果 private = 1 表明的是,资源所在的服务器地址是通过 DHT
(distributed hash table 分布式哈希表
)间接获得的

info 字段中有两个模式:1.single-file 单文件模式 2.multi-file 多文件模式
不同的文件模式组织信息的方式不同

    info字段的  单文件模式(single-file)
        
名称(关键字) 值类型 含义
name(strings类型) 4:name 值也是字符串strings 类型 用来记录共享文件的名称
length(strings类型) 6:length 值是整型 integer i以字节为单位的共享文件长度e 用来记录共享文件的长度信息
md5sum(strings 类型) 6:md5sum /// 用来记录共享文件的 md5sum 值,没见过有谁使用


    info字段的  多文件模式(multi-file)
名称(关键字) 值类型 含义
name(strings类型) 4:name 值为strings 值为多个共享文件所在的路径名称
files (strings类型) 5:files 值为包含多个 dict(字典)的列表 ld...ed...ed...ee 该 files 所对应的值是一个列表,
列表中包含多个字典,字典中记录了每个共享文件的所在路径与文件长度等信息

例如,info 是多文件模式,且多文件是 2 个文件,那么它的info 字段中的files
可以描述如下
其中 files对应的信息本身便是一个字典 de,字典中有字符串 5:files 和列表 l...e
列表中有 2 个字典 : d...e d...e
这两个字典中包含有单文件的信息,文件名和文件长度,而文件名与文件长度也是
由关键字 file , length 与值 file 的名称 与 length 的数值 这两个字典所组成的
所以,list 中的一个字典中还有两个字典
d d5:file<文件名称长度:文件名称字段>e d6:lengthe e

d5:filesldd4:file9:test1.txted6:length:i32eeeddd4:file9:test2.txted6:length:i24eeeeee
写完上面的我已经醉了....

但是这并不是重点,重点是,上面所介绍的所有字段 'announce' , 'announce-list'
等等,都是一个字典中的关键字,同时我们又知道字典中的关键字,是字符串类型;    
所以这些关键字并不是随意的一个字符串类型,而是作为字典的关键字而存在的。

   2.2 分析 .torrent 文件,从中抽取有价值信息
 下面我们来结合上面的知识分析一个简单的 .torrent 文件,从中手动抽取出有价值的信息
 

点击(此处)折叠或打开

  1. d                   ----------------------------------------> torrent 文件整体上便是一个 dictionary 的结构
  2. 8:announce          ---------------------------------------------------------------------------------------> announce关键字,后面跟着资源 URL 地址
  3. 41:
  4. 13:announce-list    ----------------------------------------> 备用URL 关键字是 announce-list ,后面跟着的值为 list
  5. l                     ------------------------------------>值 list 开始,list 中包含的元素为 子 list 结构 
  6.   l
  7.     41:80/announce
  8.     30:udp://9.rarbg.me:2710/announce
  9.   e

  10.   l
  11.     30:udp://9.rarbg.me:2710/announce
  12.   e

  13.   l
  14.     29:udp://11.rarbg.me:80/announce
  15.   e

  16.   l
  17.    29:udp://10.rarbg.me:80/announce
  18.   e

  19.   l
  20.    29:udp://12.rarbg.me:80/announce
  21.   e

  22.   l
  23.    31:udp://9.rarbg.com:2710/announce
  24.   e

  25.   l
  26.    36:udp://open.demonii.com:1337/announce
  27.   e
  28. e            ----------------------------------------------> announce-list 关键字的值 list 结束
  29.  
  30. 7:comment   ----------------------------------------> 备注信息开始,后面跟着长度 = 40 的字符串
  31.         40:Torrent downloaded from
  32. 10:created by  ------------------------------------------> 创建者信息备注,后者跟着的是长度 = 5 的字符串
  33.         5:RARBG
  34. 13:creation date i 1426207153 e -------------------------------> 创建时间备注信息,后面跟着的是一个 从 1970/1/1 00:00:00 
  35.                                                                                     开始计时到文件编写时间的秒数,整型(ie)

  36. 4:info
  37.   d ------------------>这里的 files 显然是多文件模式,请自行脑补上面 mutil-file 中各个信息字段(关键字: length 文件长度,path :文件路径
  38.    5:files   -------------------------------> files 为关键字,后面的值是一个 list 列表, 开始为 l , 结束 为 e
  39.          l  --------------------------------------------> 大列表开始
  40.             d      ---------------------------------------------------> 列表中的元素是 dict 字典类型              
  41.                 6:length i  2554803694  
  42.                 4:path
  43.                         l
  44.                           51:Into.the.Woods.2014.1080p.BluRay.H264.AAC-RARBG.mp4
  45.                         e
  46.             e
  47.             
  48.             d
  49.                6:length i   7940   e
  50.                4:path
  51.                        l
  52.                          51:Into.the.Woods.2014.1080p.BluRay.H264.AAC-RARBG.nfo
  53.                        e
  54.             e
  55.             
  56.             d
  57.                 6:length i   1016764  e
  58.                 4:path
  59.                         l 
  60.                             13:RARBG.COM.mp4
  61.                         e
  62.             e
  63.     
  64.             d
  65.                6:length  i 34  e
  66.                4:path
  67.                     l
  68.                         13:RARBG.COM.txt
  69.                     e
  70.             e
  71.             
  72.             d
  73.                 6:length  i  1557183  e
  74.                 4:path
  75.                     l
  76.                         4:Subs
  77.                         51:Into.the.Woods.2014.1080p.BluRay.H264.AAC-RARBG.idx
  78.                     e
  79.             e
  80.     
  81.             d
  82.                 6:length  i  209117184  e
  83.                 4:path
  84.                     l
  85.                         4:Subs
  86.                         51:Into.the.Woods.2014.1080p.BluRay.H264.AAC-RARBG.sub
  87.                     e
  88.             e
  89.     e  -------------------------------------------------------------------------> files 字典的值 列表结束
  90.   4:name --------------------------------------------------------------------------> 共享文件的名字,因为是 files 多文件模式,name 为多文件所在目录名称
  91.   47:Into.the.Woods.2014.1080p.BluRay.H264.AAC-RARBG
  92. e --------------------------------------------------------------------------------------------> info 的 dictionary 结束标志 'e'
  93. 12:piece length i  1048576  e   ----------------------------------------------------> 每个文件块的大小 为 1048576 B = 1024KB
  94. 6:pieces52780:??c?]??o?6ei?z?????s(牂?C?ПrK??~~c??@???];....... 略 -------------------------> 每个文件块对应的哈希码数值,
  95.                                     哈希码值为 strings 字符串类型; 长度=52780, 它可以被 20 整除合法

   e --------------------------------------> .torrent 文件结束与文件开头的 d 对应
对于多文件我的理解便是,对于一个电影文件来说,一个文件显然是不够的因为,成功播放一个电影需要 :声音文件,视频文件,
同时有可能还需要一些字幕文件等等....



下面的部分写到后续的博客中,不然文章显得太长了

3. 分析 Tracker 回复信息
    3.1 Tracker 回复信息中包含的信息字段有哪些?
    3.2 分析 Tracker 回复信息,从中抽取有价值信息

阅读(3375) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

夏目玲子2015-04-10 12:10:04

每次写完博客之后,都为自己默默的点个赞,然后看着谢谢的提示信息弹出,对自己说“客气啥,和自己不用客气!”
我觉得我的节操已经可以拿去喂狗了,