第三篇:种子文件结构
译者注:Metainfo,即,元信息,是一种专门用于“描述属性的信息”。种子文件(.torrent files)的学名叫元信息文件(Metainfo File),表示其内只有对应文件资源的元信息,因而没有真实的文件数据。一个种子文件内包含了一个或多个文件资源的元信息。
元信息文件(Metainfo File),就是我们所知道的种子文件(.torrent files),是一个 BEncoding 编码的数据文件,其整个文件的内容是一个 字典,包含如下 字段。
info
字典,描述种子内包含的文件列表信息,这里有两种类型,一是单文件的,二是多文件的,具体看后面的说明。announce
字节串,描述 Tracker 的 URL。announce-list
列表,可选,这是一个对官方规范的扩展项(参考文档:announce-list扩展字段的申请稿),提供后向兼容。creation date
字节串,可选,这是一个UNIX时间戳,表示种子文件的创建时间。comment
字节串,可选,自由描述字段,一般描述种子的制作者。created by
字节串,可选,描述用于制作这个种子文件的程序。encoding
字节串,可选,描述 info.pieces 字段的编码方式。
info 字典
无论是单文件格式还是多文件格式的种子文件,其 info 字段下都可以包含以下 3 个字段:
piece length
整数,表示一个分片的长度(单位:字节),称之为 分片单位。pieces
字节串,是由多个分片的 SHA-1校验码(20字节/个) 拼凑而成的字节串,因此其长度总是为20的倍数。private
整数,可选,如果这个值被置为1,那么 BT客户端 必须通过向 种子文件 中指定的 Tracker 汇报自身的存在,从而获取其它 伙伴 的信息。反之如果置0,客户端 可以通过其它方法获取其它伙伴,例如 PEX,DHT。因此,private 字段也可以理解为“禁止通过其它途径获取伙伴信息”。注意:Private Tracker 存在诸多争论。
参考文档:private 扩展字段的申请稿。
Azureus(BT客户端软件)最先支持了 private 字段。
单文件格式的 info 字典字段内容
当种子内仅包含一个文件的信息时,其 info 字段 内必须包括如下字段:
name
字节串,种子内包含的唯一文件的名称,这不是强制性的命名,仅作参考。(下载时可以修改保存的文件名)length
整数,种子内包含的唯一文件的大小,单位是字节。md5sum
字节串,可选,这是一个32位的16进制字符串,表示种子内包含的唯一文件的 MD5 校验值。尽管几乎所有BT客户端都未使用到这个字段,但是它仍被保留作为兼容性字段。
多文件格式的 info 字典字段内容
当种子内包含多个文件的信息时,其 info 字段 内必须包括如下字段:
name
字节串,种子内所有文件的总名称,BT客户端下载时默认使用它作为资源的目录名称,同理,这不是强制性的命名,仅作参考。(下载时可以修改保存的目录名)files
列表,这是一个由多个字典组成的列表,每个 字典 对应一个文件的信息,这些字典的格式如下:length
整数,文件的大小,单位是字节。md5sum
字节串,可选,这是一个32位的16进制字符串,表示该文件的 MD5 校验值。尽管几乎所有BT客户端都未使用到这个字段,但是它仍被保留作为兼容性字段。path
列表 这是一个特殊的文件路径表示方式。假设一个文件在种子内对应的相对路径是a/bb/ccc/hello.txt
,那么将其根据/
分割开,得到顺序列表[ 'a', 'bb', 'ccc', 'hello.txt' ]
,经过 BEncoding 编码后就是l1:a2:bb3:ccc9:hello.txte
。
注意
piece length
,即 分片单位 一般是 2 的 N 次幂。分片单位 通常根据资源文件的总体积选择,分片单位 太大会降低文件传输的效率,太小则导致 种子文件 的体积增大。从经验上看,选择 分片单位 的依据是能否将种子文件的体积控制在约 50 - 75 kB 之间(估计是为了减小服务器负担)。- 按目前的经验看来,最适合的 分片单位 是
512kb
,尽管这个大小可能导致大体积资源的种子文件体积增大,但是却能提高文件传输的效率。常用的 分片单位 有256kb
,512kb
和1MB
。 - 除了最后一个 分片 可能不同,其它每一个 分片 大小都是相同的。因此 分片 的总数等于
ceil(资源总体积 / 分片单位)
。 - 对于多文件的情况,请考虑把多个文件按照字段
info.files
里的顺序将每个文件拼接成一个长数据流,即把整个资源视为一个文件处理。这样一来,两个文件之间的边界,就可能落在同一个 分片 内。
- 按目前的经验看来,最适合的 分片单位 是
每一个 分片 都有对应的 SHA-1 哈希值。将所有的这些哈希值按顺序串联起来,就得到了
info.pieces
字段。注意info.pieces
是字节串,而不是列表。因此根据 SHA-1 哈希值的长度为 20 字节可以确定,info.pieces
的长度一定是 20 的倍数。