bt介绍以及bt种⼦的hash值(特征值)计算
bt种⼦的hansh值计算,最近忽然对bt种⼦感兴趣了(原因勿问)
1. bt种⼦(概念)
bt 是⼀个分布式⽂件分发协议,每个⽂件下载者在下载的同时向其它下载者不断的上传已经下载的数据,这样保证下载越快,上传越快,从⽽实现告诉下载
2. bt 如何实现下载同时上传⽂件
这个需要从⽂件本⾝说起,bt⽂件包含了两部分信息,⼀部分是Tracker信息,⼀部分是⽂件信息,tracker信息主要是记录下载过程中需要的tracker服务器地址和针对tracker服务器的设置,⽂件信息是根据对⽬标⽂件的计算⽣成的,计算结果会以B编码规则进⾏编码(英⽂不太好,这部分信息来⾃百度百科)。 ⽂件信息⾥,会把需要下载的⽂件进⾏分块,每个块的索引信息会写到torrent⽂件中,在这⾥上传⼀个迅雷的任务详细页⾯
可以看到具体的任务分块信息,每个下载者都可以上传⾃⼰已经下载的分块数据,如何获取其它下载者已经下载的分块信息数据呢,⼀种⽅式是通过tracker服务器来实现的,可以记录每个下载者,这也就是我们经常看见局域⽹的bt分享⽹站会有对上传下载的流量统计功能,每个⼈下载多少,上传多少,从⽽确定每个⼈的贡献值。
种子哈希转换链接这也就是海盗湾之前被瑞典起诉的原因,tracker服务器提供了给每个下载者下载盗版的可能性和机会,当然现在对于众多的magnet协议,采⽤了dht技术,这样对于tracker服务器的存在就显得没有必要了,这是后话,慢慢在描述!
3. bt的hash值计算(特征值计算)
由上可知,对于每⼀个bt种⼦,都有包含每个分块的⽂件信息,这样可以保证即使在tracker服务器有变化的情况下,bt种⼦的唯⼀性(这
⾥,插⼀句,我曾经simple的以为,可以对bt种⼦取md5值就可以确定其唯⼀性,too naive啊),那如何计算这个hash值呢,这需要对bt
⽂件组成的⼀个深⼊了解,这⽅⾯以后相当多的⽂章,附上⼀篇:
根据这篇⽂章的描述,谢了两段测试程序:
⽅法1:直接根据info后的字段信息即4:info后的字段,我们可以截取bt种⼦中的⼀段
例如:
d8:announce27:tk3.5qzone:8080/13:announce-listll27:tk3.5qzone:8080/el36::8000/announceel36:btfans.332第⼀个字节d代表dict意思,字典组成,4:info 代表着info字段长度为4意思,这样我们可以写下解析hash的代码值:
#!python
import hashlib
def sha1sum(src):
if not len(src):
return ""
m = hashlib.sha1(src)
return m.hexdigest()
#filename is the torrent file name
with open(filename) as f:
torrent_data = f.read()
if -1 != torrent_data.find("nodes"):
info_data =
torrent_data[torrent_data.find("info")+4:torrent_data.find("nodes")-2]
else:
info_data =
torrent_data[torrent_data.find("info")+4:len(torrent_data) - 1]
sha1_data = sha1sum(info_data)
print "the hash data of torrent is: ", sha1_data.upper()
在实际测试时,发现,在torrent中,有两种情况,⼀种是包含nodes字段信息的;⼀种是不包含nodes信息的torrent种⼦,需要分别处
理,但是这种处理的⽅式较为繁琐,也不清楚后续到底有多少的坑在⾥⾯,需要应对不同情况,于是去google了⼀下,在stackoverflow⾥⾯,提到⼀个库,即bencode库,这就是我们的第⼆种⽅案
⽅案2:
通过bencode库实现对hash值得计算(bencode库后续详细介绍和解读),代码如下(需要安encode库),地址:
#!/usr/bin/python
import sys, os, hashlib, StringIO
import bencode
def main():
# Open torrent file
torrent_file = open(sys.argv[1], "rb")
metainfo = bencode.bdecode(ad())
info = metainfo['info']
print hashlib.sha1(bencode.bencode(info)).hexdigest()
if __name__ == "__main__":
main()
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论