2007年3月3日星期六

Torrent文件格式

ed2k链接包含了文件长度和md4值,有了这两部分信息就很容易验证某个文件是否正确。而我在用BT下载某个文件前,有时想检查一下本地是否已经有了该文件的副本。可是很遗憾,我的目的无法达到,或者说不一定能够达到。

本文只涉及Toreent文件格式,TheoryOrg有一份v1.0的BT协议文本,有兴趣了解BT协议其他部分的可以自己看一下。

Torrent文件格式简单得可爱,其使用了一种叫bencoding的数据表达方法,支持四种数据格式:字符串、整数、列表、字典。一个Torrent文件就是一个经过编码的bencoding字典。bencoding的编码方式如下:

字符串
格式为“[[长度]:[数据]]”。其中第一部分长度为ASCII表示的十进制数字,两部分中间用冒号分隔。例:4:spam。
整数
格式为“[i[数据]e]"。开始标识i和结束标识e之间也是用ASCII表示的十进制数字,bencoding允许表示负数和0,所以i-3e和i0e是合法的,但不允许有先导0,故i04e非法。
列表
格式为“[l[bencoded数据]e]”。例如:l4:spami-3ee表示["spam", -3]。需要注意的是bencoding列表是有序的,解码和读取时不能打乱顺序。
字典
格式为“[d[bencoded字符串][bencoded数据]e]”。bencoding字典包含2N个bencoded数据,每2个一对,第一个字符串为[数据名],第二个为[]。例如:d3:who2:me4:lovel1:a1:bee表示{"who" => "me", "love" => ['a', 'b']}。

有了以上说明就足够解码一个Torrent文件了,而一个合法的Torrent文件包含如下内容:

info
包含文件信息的一个字典。info有单文件和多文件两种,详细说明见下。
announce
tracker服务器地址。
announce-list
可选,包含其他可用tracker服务器地址的列表。
creation date
可选,torrent文件创建时间,UNIX标准格式,表示自UTC1970年1月1日0时以来的秒数。
comment
可选,torrent创建者写的备注。
created by
可选,创建torrent文件的程序名和版本。

除以上外,Torrent文件可能还包含encoding、nodes等内容,大概是由后续版本的BT协议规定的。nodes有可能跟DHT有关。

Info字典有两种格式,以下为两种共有的部分:

piece length
每块数据的长度。
pieces
字符串格式,长度除以20即为总块数,每20字节又表示1块数据的SHA1值。
private
值为1或0的整数,可选。看不太懂什么意思,似乎是说如该值为1,则只能从torrent文件中指定的tracker服务器找别的peer,不设或为0则不限制。

只包含一个文件的Info字典:

name
文件名。
length
文件长度。
md5sum
可选,32字节长的文件MD5值。

包含多个文件的Info字典:

name
存放文件的目录名。
files
包含多个字典的列表,每个字典表示一个文件的信息。

files列表中的每个字典包含的内容:

length
文件长度。
md5sum
可选,含义同上。
path
包含一个或多个字符串的列表。0到-2个表示文件目录,最后一个表示文件名。例如["dir1", "dir2", "file.ext"]表示文件保存在dir1/dir2子目录下,文件名为file.ext。

因为BT上传和下载都用不到md5sum值,即使下载完成验证文件,也可以通过pieces包含的SHA1值来完成,所以BT协议把md5sum标记为可选。我随手找来百多个torrent文件检查了一下,创建torrent文件的程序包括Azureus、BitComet和uTorrent,没有一个torrent文件包括了md5sum。这也难怪,SHA1和MD5是完全不同的算法,要加入md5sum势必延长torrent文件的创建时间,能省自然就省了。可这样的省略,也使得我上述的目的很难达到了。

最单纯的情况下,torrent文件只包括一个目标文件的信息,那只要从本地文件创建一个torrent,再比较两个torrent的pieces部分,就可以判断出本地文件是否为目标文件的副本。问题是很多torrent文件都包括了不止一个目标文件,如果其余文件只是txt、nfo、jpg等,还可以下载回来一并验证。但如果torrent包括几个大型文件的信息,又只想验证本地是否有其中一个文件的副本,则几乎没办法做到了。

假如有md5sum,一切会变得非常简单。我测试所用的那些torrent中,绝大部分都是BitComet创建的。不知道写信给作者提建议,他会不会理我。

没有评论 :