开发者社区> 技术小美> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

B编码以及BT种子文件分析

简介:
+关注继续查看

去年年末的时候,有个朋友说要做一个BT协议的上传和下载,要俺帮忙,于是在那个时候搜寻了各种关于种子文件的文件格式资料。顺便整了一个BT格式的分析类库出来。目前,貌似朋友那便没说要继续整BT协议的上传和下载了,估计大概换了协议吧,呵呵。所以这个放在手里也用处不大了,刚好又很久没写博了,这个就作为当年的第一篇开篇博客吧。言归正传,正文开始

   说到BT的种子文件格式,首先我们必须要了解的就是Bencoding编码格式。关于这个格式的定义,基本上还是比较简明的,B编码总共只支持4种类型,既整数,字符串,列表和字典。整数以i标记开头以e标记结尾,中间是整数数字,字符串以:标记开头然后根接字符串的长度,最后是字符串内容,列表以l标记开头,以e结尾,字典以d开头以e结尾。列表可以包含任何的BT元素,字典也可以包含任何的BT元素,不过字典的Key必须是字符串。如此以来分析,整数和字符串是两种单元的元素,可以很好的解析,基本上不用分析就能搞定,而列表和字典,则就需要根据给定的字符串进行分析处理了,这个分析实际上也简单,先碰到开头的标记,然后不断的往下判断读取,碰到结尾标记e结束,如果在碰到结尾标记之前还又碰到其他的标记,则可进行递归处理,所以,处理起来也方便了。

    B编码解析完成,那么BT种子文件的处理也就简单了。BT种子文件实际上就是由B编码的字典组成,其内部的字典键介绍,可以参考相关资料,这里我摘录一些如下:

Torrent文件内的数据结构分为以下几部分:

announce:Tracker的主服务器

announce-list:Tracker服务器列表

comment:种子文件的注释

comment.utf-8:种子文件注释的utf-8编码

creation date:种子文件建立的时间,是从1970年1月1日00:00:00到现在的秒数。

encoding:种子文件的默认编码,比如GB2312,Big5,utf-8等

info:所有关于下载的文件的信息都在这个字段里,它包括多个子字段,而且根据下载的是单个文件还是多个文件,子字段的项目会不同。

当种子里包含多个文件时,info字段包括如下子字段:

files:表示文件的名字,大小,该字段包含如下三个子字段:

        lenghth:文件的大小,用byte计算

         path:文件的名字,在下载时不可更改

          path.utf-8:文件名的UTF-8编码,同上


以上的三个字段每个文件都有一组值。

name:推荐的文件夹名,此项可于下载时更改。

name.utf-8:推荐的文件夹名的utf-8编码,同上。

piece length:每个文件块的大小,用Byte计算

pieces:文件的特征信息,该字段比较大,实际上是种子内包含所有的文件段的SHA1的校验值的连接,即将所有文件按照piece length的字节大小分成块,每块计算一个SHA1值,然后将这些值连接起来就形成了pieces字段,由于SHA1的校验值为20Byte,所以该字段的大小始终为20的整数倍字节。该字段是Torrent文件中体积最大的部分,可见如果大文件分块很小,会造成Torrent文件体积庞大。

publisher:文件发布者的名字

publisher.utf-8:文件发布者的名字的utf-8编码

publisher-url:文件发布者的网址

publisher-url.utf-8:文件发布者网址的utf-8编码。

另外,当发布单文件时,files字段是没有的,而


lenghth:
name:
name.utf-8:


这三个字段负责描述单文件的属性:大小,名字,名字的utf-8编码。其他项目和多文件相同。

以上的项目即为info字段的全部。

说到info就不得不说
INFO_HASH,这个值是info字段的HASH值,20个Byte,同样是使用SHA1作为HASH函数。由于info字段是发布的文件信息构成的,所以INFO_HASHBT协议中是用来识别不同的种子文件的。基本上每个种子文件的INFO_HASH都是不同的(至少现在还没有人发现有SHA的冲突),所以BT服务器以及客户端都是以这个值来识别不同的种子文件的。

计算的具体范围是从info字段开始(不包含"info"这四个字节),一直到nodes字段为止(不包含"nodes"这5个字节和nodes前边表示nodes字段长度的"5:"这两个字节)。另外,
INFO_HASH值是即时计算的,并不包含在Torrent文件中。

nodes:最后的一个字段是nodes字段,这个字段包含一系列ip和相应端口的列表,是用于连接DHT初始node。

综上,多文件Torrent的结构的树形图为:

Multi-file Torrent
├─announce
├─announce-list
├─comment
├─comment.utf-8
├─creation date
├─encoding
├─info
│ ├─files
│ │ ├─length
│ │ ├─path
│ │ └─path.utf-8
│ ├─name
│ ├─name.utf-8
│ ├─piece length
│ ├─pieces
│ ├─publisher
│ ├─publisher-url
│ ├─publisher-url.utf-8
│ └─publisher.utf-8
└─nodes

单文件Torrent的结构的树形图为:

Single-File Torrent
├─announce
├─announce-list
├─comment
├─comment.utf-8
├─creation date
├─encoding
├─info
│ ├─length
│ ├─name
│ ├─name.utf-8
│ ├─piece length
│ ├─pieces
│ ├─publisher
│ ├─publisher-url
│ ├─publisher-url.utf-8
│ └─publisher.utf-8
└─nodes


BT类库文件简码:

复制代码
//B编码支持的数据类型
TDxBenValueTypes = (DBV_String,DBV_Int,DBV_List,DBV_Dictionary);
//B编码的节点,类似于JSON节点,
TDxBenValue = class
private
FParent: TDxBenValue;
protected
function GetType:TDxBenValueTypes; virtual; abstract;
procedure Parser(str: string);virtual;abstract;
function GetAsInteger: Integer;virtual;abstract;
function GetAsString: string;virtual;abstract;
function GetObject: TDxBenValue;virtual;
public
constructor Create;overload;virtual;
constructor Create(str: string);overload;virtual;
property ValueType: TDxBenValueTypes read GetType;
function ToString: string;override;
property Parent: TDxBenValue read FParent;
property AsInteger: Integer read GetAsInteger;
property AsString: string read GetAsString;
property AsValueObject: TDxBenValue read GetObject;
end;

TDxBenInt = class(TDxBenValue)
private
FValue: Integer;
protected
function GetType:TDxBenValueTypes;override;
function GetAsInteger: Integer;override;
procedure Parser(str: string);override;
function GetAsString: string;override;
function GetObject: TDxBenValue;override;
public
constructor Create;override;
function ToString: string;override;
end;

TDxBenString = class(TDxBenValue)
private
FValue: string;
protected
function GetType:TDxBenValueTypes;override;
function GetAsString: string;override;
function GetObject: TDxBenValue;override;
function GetAsInteger: Integer;override;
procedure Parser(str: string);override;
public
function ToString: string;override;
end;

TDxBenDictionary = class;
TDxBenList = class(TDxBenValue)
private
FList: TList;
function GetCount: Integer;
function GetValues(index: Integer): TDxBenValue;
protected
procedure Parser(str: string);override;
procedure ParserToList(var P: Pchar;List: TDxBenList);
procedure ParserToDictionary(var p: PChar;Dict: TDxBenDictionary);
function GetType:TDxBenValueTypes;override;
function GetAsString: string;override;
function GetObject: TDxBenValue;override;
function GetAsInteger: Integer;override;
public
procedure Clear;
constructor Create; override;
constructor CreateFromString(str: string);
destructor Destroy;override;
function ToString: string;override;
property Count: Integer read GetCount;
property Values[index: Integer]: TDxBenValue read GetValues;
end;

TDxBenDictionary = class(TDxBenValue)
private
FDict: TDictionary<string,TDxBenValue>;
function GetCount: Integer;
function GetValues(Key: string): TDxBenValue;
protected
procedure ParserToList(var P: Pchar;List: TDxBenList);
procedure ParserToDictionary(var p: PChar;Dict: TDxBenDictionary);

procedure Parser(str: string);override;
function GetType:TDxBenValueTypes;override;
function GetAsString: string;override;
function GetObject: TDxBenValue;override;
function GetAsInteger: Integer;override;
public
procedure Clear;
constructor Create;override;
destructor Destroy;override;
function ToString: string;override;
property Count: Integer read GetCount;
property Values[Key: string]: TDxBenValue read GetValues;
end;

TDxBtInfo = class(TDxBenDictionary)
private
function GetSingleFile: Boolean;
function GetFiles: TDxBenList;
function GetName: string;
function GetNameUtf8: string;
function Getpublisher: string;
function GetpublisherUtf8: string;
function Getpublisherurl: string;
function GetpublisherurlUtf8: string;
public
property SingleFile: Boolean read GetSingleFile;
property Files: TDxBenList read GetFiles;
property Name: string read GetName;
property NameUtf8: string read GetNameUtf8;
property publisher: string read Getpublisher;
property publisherUtf8: string read GetpublisherUtf8;
property publisherurl: string read Getpublisherurl;
property publisherurlUtf8: string read GetpublisherurlUtf8;
end;

TDxTorrentFile = class
private
FDict: TDxBenDictionary;
procedure ParserStream(Stream: TStream;Dict: TDxBenDictionary);overload;
procedure ParserStreamToList(Stream: TStream; List: TDxBenList);
function GetComment: string;
function GetEncoding: string;
function GetCreator: string;
function Getannounce: string;
function Getannounce_list: TDxBenList;
function GetBtInfo: TDxBtInfo;
function GetCreateDate: TDateTime;
public
procedure Clear;
constructor Create;
destructor Destroy;override;
procedure LoadFromFile(FileName: string);
procedure LoadFromStream(Stream: TStream);
property Comment: string read GetComment;
property Encoding: string read GetEncoding;
property Creator: string read GetCreator;
property announce: string read Getannounce;
property announce_list: TDxBenList read Getannounce_list;
property BtInfo: TDxBtInfo read GetBtInfo;
property CreateDate: TDateTime read GetCreateDate;
end;
implementation
end.


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
springboot 各种文件下载方式(最全)
springboot 各种文件下载方式(最全)
15 0
神器 SpringDoc 横空出世!最适合 SpringBoot 的API文档工具来了
之前在SpringBoot项目中一直使用的是SpringFox提供的Swagger库,上了下官网发现已经有接近两年没出新版本了!前几天升级了SpringBoot 2.6.x 版本,发现这个库的兼容性也越来越不好了,有的常用注解属性被废弃了居然都没提供替代!无意中发现了另一款Swagger库SpringDoc,试用了一下非常不错,推荐给大家! SpringDoc简介 SpringDoc是一款可以结合SpringBoot使用的API文档生成工具,基于OpenAPI 3,目前在Github上已有1.7K+Star,更新发版还是挺勤快的,是一款更好用的Swagger库!值得一提的是SpringDoc
67 0
【综合笔试题】根据答案具有「二段性」进行二分滑动窗口求解|Java 刷题打卡
【综合笔试题】根据答案具有「二段性」进行二分滑动窗口求解|Java 刷题打卡
74 0
Could not autowire. No beans of *** type found
Could not autowire. No beans of *** type found
53 0
Spring Boot项目使用maven-assembly-plugin根据不同环境打包成tar.gz或者zip
Spring Boot项目使用maven-assembly-plugin根据不同环境打包成tar.gz或者zip
4627 0
gvim如何制定打开文件的编码字符集?
上个星期遇到的问题,今天google看看,发现如下链接,测试可以正常的使用与显示: http://python.cn/pipermail/python-chinese/2006-August/028502.
683 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载