BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / soft-design / #42090同步于 2012/3/27
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖

迅雷Hash算法分析

binux
2012/3/27镜像同步16 回复
看了看,估计也就和这个版沾边吧。。。 当迅雷刚出现的时候,那个神奇的P2SP让很多人惊叹(当然让站长们头疼)。无论是热门的下载链接、第一次遇到的冷门地址,还是死链,它都能匹配到资源完成下载。据传它是根据文件名+文件大小来判断,佐证就是有可能会下到错误的文件。。那迅雷究竟做了些什么,其实看看hash算法就知道了。。 ================================================================= 从迅雷离线获得的地址中,存在着大量的Hash值,这些hash看似都是base64,sha1,md5但却有所不同。 比如这是一个典型的离线地址 http://gdl.lixian.vip.xunlei.com/download? fid=3KUoDlBy9IotAFn5vQAHc5VUIgKiwSgmAAAAAHYA3duVUUeWgaJI4JGu5syK9PLK& // base64: 与cid,size,gcid相关(size为小字节序) mid=666& // maybe: always 666 threshold=150& // maybe: always 150 tid=A950BAE38A2E7398186D4127315DB76F // unknow: 256bit relate with size srcid=4 // maybe: always 4 verno=1 // maybe: always 1 g=7600DDDB9551479681A248E091AEE6CC8AF4F2CA& // gcid: for normal download gcid == cid scn=c7& // section i=3547930B96AFA7B0A1CFCC80D516ADE97A34DAE0& // cid == infoid == btih == ed2k hash, files share a same cid in a bt task, cid is the btih of the torrent t=6& // type: 1=normal 4=ed2k 6=bt ui=18×××9640& //userid ti=33742×××247& //tid from get free url s=640205218& //totalByte m=0& // mayby: always 0 n=01324486025B4775690D459D7F43726F770F6CBF6F345D5B46347DA817445D5B422876D1025B783236556EA51C335D2E6D0A47E45F00000000 // filename 根据已有的数据分析/比对,大致各个字段的含义已经标识出来了。其中除了ui,ti是与用户相关的变元,i是来源相关的变元,其他的字段对于某一个文件来说一般是相同的。 cid 算法源码: def cid_hash_file(path): h = hashlib.sha1() size = os.path.getsize(path) with open(path, 'rb') as stream: if size < 0xF000: h.update(stream.read()) else: h.update(stream.read(0x5000)) stream.seek(size/3) h.update(stream.read(0x5000)) stream.seek(size-0x5000) h.update(stream.read(0x5000)) return h.hexdigest().upper() 算法来自于https://github.com/iambus/xunlei-lixian。 在api中,cid主要用于文件的索引。观察代码可知,cid并没有hash整个文件,而是根据文件的头/中/尾部的0×5000字节的内容计算Hash。这样就可以在不下载完整个文件,就能够查询到其他服务器上可能的相同文件。于是在下载支持range的文件的时候,即使该地址没有被索引到,但是通过cid,依旧可以被p2sp加速。 当然了,由于没有hash整个文件,文件在事实上有可能是不同的,那么根据下面这个gcid就可以唯一确定一个文件了。 gcid def gcid_hash_file(path): h = hashlib.sha1() size = os.path.getsize(path) psize = 0x40000 while size / psize > 0x200: psize = psize << 1 with open(path, 'rb') as stream: data = stream.read(psize) while data: h.update(hashlib.sha1(data).digest()) data = stream.read(psize) return h.hexdigest().upper() 这个算法借助了18万个已有文件的数据,以及迅雷咖啡吧上的一句话:“如果文件很大,则计算gcid非常耗时,因此可以在大文件传输过程中计算gcid,文件传输完毕,则gcid也计算好了“。。 gcid的作用是文件的唯一键,在迅雷服务器上唯一确定一个文件。可以说,只要有了gcid,实际上是可以任意下载到指定文件的。算法采用了分片hash再二次sha1的算法。。猜测原因是因为分片被限制在512个一下,当hash较大文件的时候,可以边下载边hash,再在最后hash那个不到512*20字节的串即可,当文件下载完成的时候就能立即得出gcid。还有一个原因是bt文件也是用sha1分片Hash的,那么获得种子文件也就同时有可能获得gcid了。同时,如果迅雷服务器保存了每个分片的sha1 hash的话,那么在下载通过cid匹配的文件同时,就能同时比较各个分片是否正确,以此保证最终结果正确。 fid def parse_fid(fid): cid, size, gcid = struct.unpack("<20sq20s", fid.decode("base64")) return cid.encode("hex").upper(), size, gcid.encode("hex").upper() def gen_fid(cid, size, gcid): return struct.pack("<20sq20s", cid.decode("hex"), size, gcid.decode("hex")).encode("base64").strip() 首先这很明显是一个base64,但是一开始我并没有发现她们和cid,size,gcid的关系,[del]直到我膝盖中了一箭[/del]。。 fid就是cid,size,gcid的二进制然后再base64而已。但是有了fid,神马cid,size,gcid这三大要素都不是问题了。应该是用于api分析url的便利,所做的一个接口性参数。 tid 未知算法。 根据18万的文件数据,唯一能够知道的是,这个tid和文件大小一一对应。。size相同的文件tid一定相同,但是又不是size的直接hash,目前来说完全不知道这个参数的意义何在。。难道这个hash印证了迅雷根据文件大小来确定文件? 如果有兴趣,您可以在https://github.com/binux/lixian.xunlei/blob/master/tid.dict文件里面找到目前已知的映射。。如果分析出算法了请务必告诉我。 ==== 由上面的分析可见,一个文件的离线地址完全就是根据文件的信息生成的,于是这意味着什么?知道了算法,我们完全不需要通过迅雷服务器就可以生成自己的离线地址!如果这个文件在迅雷服务器上存在,我们可以直接下载回来!(等等,你说参数n。。那不就是文件名嘛。。我只关心内容。。文件名这种小问题。。) 说到做到,您可以现在就可以通过https://github.com/binux/lixian.xunlei/blob/master/check_file.py这个脚本直接计算出文件的cid,gcid,fid,并且检测文件在迅雷服务器上是否存在。 然后,把fake_url添加到迅雷软件里面。然后。。就可以直接下载了!可以开启高速通道,可以在快盘秒传,运气好可以开启离线秒传。。。 ============ 鉴于迅雷离线在教育网不可用,这个项目的本体就不在论坛上发了。。相关资源: 原文:http://blog.binux.me/2012/03/hash_algorithm_of_xunlei/ 源码:https://github.com/binux/lixian.xunlei
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
iFadeToBlack机器人#1 · 2012/3/27
赞!
times123机器人#2 · 2012/3/27
威武哇
buptpk机器人#3 · 2012/3/27
看完第一想到的是http://loli.lu/,然后看楼主昵称才反应过来那网站就是楼主建的。。
allenbo机器人#4 · 2012/3/27
强大啊!
antique机器人#5 · 2012/3/27
赞。
edious机器人#6 · 2012/3/27
NB
Truman机器人#7 · 2012/3/28
llyzltz机器人#8 · 2012/3/28
强大
wo1f5x机器人#9 · 2012/3/29
orz LZ强人!