新建一个文本文件 ,文件 内容 为123456,用Bittorrent客户端制作种子文件 :
d8:announce44:udp://tracker.openbittorrent.com:80/announce13:announce-listll44:udp://tracker.openbittorrent.com:80/announceel42:udp://tracker.opentrackr.org:1337/announceee7:comment18:this is a comment.10:created by17:BitTorrent/7.10.513:creation datei1628327795e8:encoding5:UTF-84:infod6:lengthi6e4:name7:dos.txt12:piece lengthi16384e6:pieces20:|J?? ?ê7bˉa?? ”=?d”?”ee
64 38 3A 61 6E 6E 6F 75 6E 63 65 34 34 3A 75 64 70 3A 2F 2F 74 72 61 63 6B 65 72 2E 6F 70 65 6E 62 69 74 74 6F 72 72 65 6E 74 2E 63 6F 6D 3A 38 30 2F 61 6E 6E 6F 75 6E 63 65 31 33 3A 61 6E 6E 6F 75 6E 63 65 2D 6C 69 73 74 6C 6C 34 34 3A 75 64 70 3A 2F 2F 74 72 61 63 6B 65 72 2E 6F 70 65 6E 62 69 74 74 6F 72 72 65 6E 74 2E 63 6F 6D 3A 38 30 2F 61 6E 6E 6F 75 6E 63 65 65 6C 34 32 3A 75 64 70 3A 2F 2F 74 72 61 63 6B 65 72 2E 6F 70 65 6E 74 72 61 63 6B 72 2E 6F 72 67 3A 31 33 33 37 2F 61 6E 6E 6F 75 6E 63 65 65 65 37 3A 63 6F 6D 6D 65 6E 74 31 38 3A 74 68 69 73 20 69 73 20 61 20 63 6F 6D 6D 65 6E 74 2E 31 30 3A 63 72 65 61 74 65 64 20 62 79 31 37 3A 42 69 74 54 6F 72 72 65 6E 74 2F 37 2E 31 30 2E 35 31 33 3A 63 72 65 61 74 69 6F 6E 20 64 61 74 65 69 31 36 32 38 33 32 37 37 39 35 65 38 3A 65 6E 63 6F 64 69 6E 67 35 3A 55 54 46 2D 38 34 3A 69 6E 66 6F 64 36 3A 6C 65 6E 67 74 68 69 36 65 34 3A 6E 61 6D 65 37 3A 64 6F 73 2E 74 78 74 31 32 3A 70 69 65 63 65 20 6C 65 6E 67 74 68 69 31 36 33 38 34 65 36 3A 70 69 65 63 65 73 32 30 3A 7C 4A 8D 09 CA 37 62 AF 61 E5 95 20 94 3D C2 64 94 F8 94 1B 65 65
上面为对应文本,下面为对应的16进制源;可见,种子文件是bencode编码的,这个种子文件的info_hash磁力算法:涉及以下几个字段,就是info字典,但要重新sha1,需要解码
infod6:lengthi6e4:name7:dos.txt12:piece lengthi16384e6:pieces20:|J?? ?ê7bˉa?? ”=?d”?”ee
def torrent_file_to_magnet(torrent_file):
data = open(torrent_file, 'rb').read() #读文件
metadata = bencode.bdecode(data) #bcode解码还原
print('------------------------------')
print(metadata['info']) #还原info
print('------------------------------')
name = metadata['info']['name']
#metadata['info']['name']='x' #假设更改name字段,看是否变,事实上,变了
print(metadata['info']['name'])
dn = quote(name)
info_bts = bencode.bencode(metadata['info'])
info_hash = hashlib.sha1(info_bts).hexdigest()
return f'magnet:?xt=urn:btih:{info_hash}&dn={dn}'
#输出的metadate['info']
OrderedDict([('length', 6), ('name', 'dos.txt'), ('piece length', 16384), ('pieces', b'|J\x8d\t\xca7b\xafa\xe5\x95 \x94=\xc2d\x94\xf8\x94\x1b')])
也就是说,种子文件是 length,name,pice length,pieces这几个字段经过bencode后,最后sha1算法得到的;解,编,实际上,就是info字段sha1后的结果;
d6:lengthi2715254784e4:name30:ubuntu-20.04-desktop-amd64.iso12:piece lengthi1048576e6:pieces51800:
在种子文件中,从info后开始,尾部去e(多了一个e;);这段内容,经sha1编码,就是info_hash;就是磁力链接
res = '123456'
print(hashlib.sha1(res.encode('utf-8')).hexdigest())
//输出:
7c4a8d09ca3762af61e59520943dc26494f8941b
上面的输出 就是文本文件 123456的piceces内容对应:7C 4A 8D 09 CA 37 62 AF 61 E5 95 20 94 3D C2 64 94 F8 94 1B ,也就是最上面的种子文件 的内容;
把d6:lengthi6e4:name7:dos.txt12:piece lengthi16384e6:pieces20:|J?? ?ê7bˉa?? ”=?d”?”这段内容sha1后,就是磁力链接
|