范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

BT背后的技术

  历史
  早期的BT下载主要是通过开放的网站,进行种子资源的公布。在利用tracker中心服务器完成下载peer的交换,最终实现从下载用户的电脑中获取资源。
  在这个过程中,存在两个风险比较大的点:
  第一个公布种子的网站,种子文件包含了所需要下载资源的全部信息,很容易被检测出种子内容是否合规,从而关闭种子公布资源站点。
  第二个提供tracker的中心服务节点,这个也是很容易从种子中查询到的,很容易被封杀。导致P2P自由的分享环境被打破。
  在这个基础上,就出现替代tracker服务器和种子一些新方法,我们简单的介绍下比较主流的去中心化tracker和种子分享网站的P2P分享网络。
  torrent and magnet
  首先从第一步获取种子开始,我们一般想找一部电影/游戏或者一些其他资源,一般都是网盘搜索,或者去BT站,PT去找种子,或者论坛上去找链接。先介绍下种子和磁链的关系,种子一般以.torrent结尾的索引文件。 torrent d8:announce62:https://xxxxx.im.xxx/88696dc48cbdad7518e4b111b83ee77c7:comment14:TorrenTGui.ORG10:created by13:uTorrent/221013:creation datei1523099215e8:encoding5:UTF-84:infod6:lengthi23715250176e4:name14:SKY HUNTER.iso12:piece lengthi4194304e6:pieces113100:xxx
  这种被序列化的信息就是种子了,里面使用的是一种明文的序列化方法。bencode 第二节简单介绍。
  反序列化里面主要包含以下信息: announce:Tracker的主服务器 announce-list:Tracker服务器列表 comment:种子文件的注释 comment.utf-8:种子文件注释的utf-8编码 creation date:种子文件建立的时间,是从1970年1月1日00:00:00到现在的秒数。 encoding:种子文件的默认编码,比如GB2312,Big5,utf-8等 info:所有关于下载的文件的信息都在这个字段里,根据下载的是单个文件还是多个文件,子字段的项目会不同。 files:表示文件的名字,大小,该字段包含如下三个子字段: length:文件的大小,用byte计算 path:文件的名字,在下载时不可更改 path.utf-8:文件名的UTF-8编码,
  多文件Torrent的结构的树形图为 Multi-file Torrent ├─announce ├─announce-list ├─comment ├─comment.utf-8 ├─creation date ├─encoding ├─info │ ├─files │ │ ├─length │ │ ├─path │ │ └─path.utf-8 │ ├─name │ ├─name.utf-8 │ ├─piece length │ ├─pieces │ ├─publisher │ ├─publisher-url │ ├─publisher-url.utf-8 │ └─publisher.utf-8 └─nodes
  单文件Torrent的结构的树形图为 Single-File Torrent ├─announce ├─announce-list ├─comment ├─comment.utf-8 ├─creation date ├─encoding ├─info │ ├─length │ ├─name │ ├─name.utf-8 │ ├─piece length │ ├─pieces │ ├─publisher │ ├─publisher-url │ ├─publisher-url.utf-8 │ └─publisher.utf-8 └─nodesmagnet
  为了解决第一种子文件包含的内容信息太多,容易被检测中其中的关键信息。第二种子文件过大,不太容易扩散分享。出现了一种替代种子文件的信息字符串就是磁力链接。形如:magnet:?xt=urn:btih:b7d9b9d9df8d7678af1f2542677e195fdbdb1674
  其中主要字段是 btih,其实这里的值就是bt种子文件中info字段sha1值的base32编码后的字符串。
  bencode
  种子文件的bencode 包含四种类型的编码: string类型
  string类型的编码格式为[length]:[string]。以字符串的长度开头,加一个冒号,并以字符串内容结束。
  示例:"abc" => 3:abc int类型
  int类型的编码格式为i[int]e。以i开头,加上数字,以e结尾。
  示例:123 => i123e List类型
  List类型的编码格式为l[object]e。以l开头,加上列表中各个元素的编码(元素的类型同样为BEncoding支持的类型),以e结尾。
  示例:List<"abc", 123> => l3:abci123ee Dictionary类型
  Dictionary类型的编码格式为d[Key-Value Pair]e。以d开头,加上字典中每个键值对的编码,以e结尾。
  示例:Dictionary<{"name":"create chen"},{"age":23}> => d4:name11:create chen3:agei23ee
  以上编码list和dictionary支持嵌套。bencode编码方式也被用在后续的BT查询消息的构建上。
  去中心化的peer交换网络 DHT
  在去中心化的交换网络上,每个用户(node)都会存储一部分种子信息和种子索引信息。这些索引信息里面包含自己正在下载的资源(peer)、自己周边正在下载的资源信息(peer)、以及一些可能拥有某种子资源的信息(node)。当我们获取到某个种子或者磁链时,就会到这个网络中查询哪些用户在进行这个种子的资源下载,获取这些用户的peer信息(包含ip port token),然后和这些peer进行连接,获取资源。在查询的过程中,主要利用krpc进行调用,krpc是一种基于udp的rpc调用服务。
  krpc
  基本结构如下: {     "t":"aa", --transcationID  2^16  two byte     "y":"r",  --message type query->q response->r error->e     "q":" ".  --ping find_node get_peers     "r":{}     "e"     "a":      --query params }
  一条 KRPC 消息由一个独立的字典组成,其中有 2 个关键字是所有的消息都包含的,其余的附加关键字取决于消息类型。每一个消息都包含"t"关键字,它是一个代表了 transaction ID 的字符串类型。transaction ID由请求节点产生,并且回复中要包含回显该字段,所以回复可能对应一个节点的多个请求。transaction ID应当被编码为一个短的二进制字符串,比如 2 个字节,这样就可以对应 2^16 个请求。另一个每个 KRPC 消息都包含的关键字是"y",它由一个字节组成,表明这个消息的类型。y 对应的值有三种情况:q 表示请求,r 表示回复,e 表示错误。
  主要包含以下四个操作: ping
  检测节点是否存活。
  最基础的请求是一个ping。"q"="ping",一个ping请求有一个参数,"id",它的值是一个20字节的字符串,包含网络字节排序的发送者的节点ID。一个ping的适当回复有一个关键字"id",包含发出回复的节点的节点ID。 arguments:  {"id" : ""} response: {"id" : ""}  Example Packets  ping Query = {"t":"aa", "y":"q", "q":"ping", "a":{"id":"abcdefghij0123456789"}} bencoded = d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe Response = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}} bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:refind_node
  查找节点。
  find_node 被用来查找给定 ID 的节点的联系信息。这时 KPRC 协议中的 "q" == "find_node"。find_node请求包含 2 个参数,第一个参数是 id,包含了请求节点的ID。第二个参数是 target,包含了请求者正在查找的节点的ID。当一个节点接收到了 find_node 的请求,他应该给出对应的回复,回复中包含 2 个关键字 id 和 nodes,nodes 是一个字符串类型,包含了被请求节点的路由表中最接近目标节点的 K(n) 个最接近的节点的联系信息。在规范的DHT网络中,K(n)建议值是8。 arguments:  {"id" : "", "target" : ""} response: {"id" : "", "nodes" : ""}  Example Packets find_node Query = {"t":"aa", "y":"q", "q":"find_node", "a": {"id":"abcdefghij0123456789", "target":"mnopqrstuvwxyz123456"}} bencoded = d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe Response = {"t":"aa", "y":"r", "r": {"id":"0123456789abcdefghij", "nodes": "def456..."}} bencoded = d1:rd2:id20:0123456789abcdefghij5:nodes9:def456...e1:t2:aa1:y1:reget_peers
  查找文件peer。
  get_peers 与 torrent 文件的 infohash 有关。这时 KPRC 协议中的 "q"="get_peers"。get_peers 请求包含 2 个参数。第一个参数是 id,包含了请求节点的 ID。第二个参数是info_hash,它代表 torrent 文件的 infohash。如果被请求的节点有对应 info_hash 的peers,他将返回一个关键字 values,这是一个列表类型的字符串。每一个字符串包含了 "CompactIP-address/portinfo" 格式的 peers 信息。如果被请求的节点没有这个 infohash 的peers,那么他将返回关键字 nodes,这个关键字包含了被请求节点的路由表中离 info_hash 最近的 K 个节点, arguments:  {"id" : "", "info_hash" : "<20-byte infohash of target torrent>"} response: {"id" : "", "token" :"", "values" : ["", ""]}    or: {"id" : "", "token" :"", "nodes" : ""}  Example Packets  get_peers Query = {"t":"aa", "y":"q", "q":"get_peers", "a": {"id":"abcdefghij0123456789", "info_hash":"mnopqrstuvwxyz123456"}} bencoded = d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe Response with peers = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "values": ["axje.u", "idhtnm"]}} bencoded = d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:axje.u6:idhtnmee1:t2:aa1:y1:re Response with closest nodes = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "nodes": "def456..."}} bencoded = d1:rd2:id20:abcdefghij01234567895:nodes9:def456...5:token8:aoeusnthe1:t2:aa1:y1:reannounce_peer
  发起请求节点。
  这个请求用来表明发出 announce_peer 请求的节点,正在某个端口下载 torrent 文件。announce_peer 包含 4个参数。第一个参数是 id,包含了请求节点的 ID;第二个参数是 info_hash,包含了 torrent 文件的infohash;第三个参数是 port 包含了整型的端口号,表明 peer 在哪个端口下载;第四个参数数是 token,这是在之前的get_peers 请求中收到的回复中包含的。收到 announce_peer 请求的节点必须检查这个 token 与之前我们回复给这个节点get_peers 的 token 是否相同。如果相同,那么被请求的节点将记录发送 announce_peer 节点的 IP 和请求中包含的port 端口号在 peer 联系信息中对应的 infohash 下。 arguments:  {"id" : "",   "implied_port": <0 or 1>,   "info_hash" : "<20-byte infohash of target torrent>",   "port" : ,   "token" : ""}  response: {"id" : ""} Example Packets  announce_peers Query = {"t":"aa", "y":"q", "q":"announce_peer", "a": {"id":"abcdefghij0123456789", "implied_port": 1, "info_hash":"mnopqrstuvwxyz123456", "port": 6881, "token": "aoeusnth"}} bencoded = d1:ad2:id20:abcdefghij012345678912:implied_porti1e9:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe Response = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}} bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re
  DHT and Kademlia
  DHT (Distributed Hash Table)分布式哈希表,Kad网络是其的一种实现方式。Kademlia协议(以下简称Kad)是美国纽约大学的PetarP. Maymounkov和David Mazieres.在2002年发布的一项研究结果《Kademlia: A peerto -peer information system based onthe XOR metric》。 nodeid
  2^160位(bit)的标志id,可以是本机mac的sha1值。在DHT分享网络中,资源的info-hash正好也是160位(bit)。在利用kad网络,将info-hash存储于与其相近的多个node中,方便在查询过程中利用get_peer进行快速逼近。在如何判定是否与其相近,kad网络利用的是xor运算。
  xor distance
  Kademlia 根据两个标示符之间的距离来把  对分配给特定的节点。对于两个 160 位标示符 x 和 y , Kademlia 把它们之间的距离定义为二者按位异或( XOR )结果的整数值, d(x,y)=x ⊕y 。
  首先,XOR 是一种有效的度量方法(虽然不是欧几里得几何意义上的)。很显然,d(x,x)=0 ;当x 不等于y 时,d(x,y)>0 ,并且对于任意的x,y 来说,d(x,y)=d(y,x) 。XOR 还具有三角特性:d(x,y)+d(y,z) 大于等于d (x,z )。该三角特性可以从如下事实得出:d(x,y) ⊕d(y,z)=d(x,z) ,并且对于任意大于等于0 的a 和b :a+b 都大于等于a ⊕b 。
  同时,XOR 也刻画出了隐含在我们基于二叉树描绘的系统中距离的概念。在160 位ID 的满二叉树中,两个IDs 间的距离大小就是包含它们的最小子树的高度。当树不是满的时,距离ID x 最近的叶子就是其ID 和x 具有最长的公共前缀的那个叶子。如果树中有空的分支,那么具有最长公共前缀的叶子就会有多个。此时,我们基于该树的空分支,把x 对应的位取反得到ID x’ ,那么距离x’ 最近的叶子即为距离x 最近的叶子。利用xor的距离测算,最坏O(n)即可获得到查询结果。
  routing table
  路由表是一颗二叉树,其叶子是 k-buckets 。每个 k-bucket 存放着具有某些公共 ID 前缀的节点。前缀就是该 k-bucket 在二叉树中的位置。了因此,每个 k-bucket 覆盖了 ID 空间的某个范围,所有 k-bucket 合起来完整覆盖了整个 160 位 ID 空间。
  节点是根据需要动态分配到路由树中的。一开始,节点A的路由树只有一个节点——覆盖整个 ID 空间的单个 k-bucket 。当A通过find_node或者get_peer获取一个新节点的联系信息时,就会试图把其插入到相应的 k-bucket 中。如果该 bucket 不满,简单将其插入即可。否则,如果该 k-bucket 的区间范围包含了A自己的节点 ID ,那么该 bucket 会分裂为两个新的 buckets ,原有的内容会被划分到这两个 buckets 中,接着重复插入过程。如果 k-bucket 已满且不含有A的节点 ID ,那么就直接丢弃这个新的联系信息。需要注意的是P2P节点在线时间是不稳定的,需要定期去ping检测每个k-bucket捅中的节点,如果死掉则剔除掉。按照beps005规范没有更新的节点15分钟需要检测一次。每次krpc操作中可以正常响应的则认为是活跃节点。
  在Kad网络中还存在一种高度不平衡的二叉树均衡的过程,在BT的DHT网络中,目前没有看到使用。
  BT 爬虫实现要点
  1.先伪装自己向公共节点进行find_node 查询,将自己加入网络。 "router.bittorrent.com:6881", "router.utorrent.com:6881", "dht.transmissionbt.com:6881",
  2.在返回的find_node中,替换返回nodeid的某些n位,造成与返回node节点id不在区间内,继续探索整个网络节点分布。 func CreateRandomFindNode(target string) (res []byte, transid string) { msg := make(map[string]interface{})     msg["t"] = TCIDMNGR.GetTranscationID()     msg["y"] = "q"     msg["q"] = "find_node"     msg["a"] = map[string]interface{}{"id": target[:15] + OwnNodeID.ToString()[15:], "target": target}     return []byte(PackageMessage(msg)), msg["t"].(string) }
  3.一般BT爬虫被动接收announce_peer 从peer的信息中使用peer wire protocol 获取 metadata 即种子信息。然后分析torrent中的信息确认文件内容。
  4.注意进行ip黑名单过滤,DHT网络中,存在很多这样爬虫,在实现过程中,发现北美有个ip爬虫疯狂变更nodeid进行find_node 请求,把内存塞满的情况(1G),注意控制本地DHT表的总节点数。
  5.加速搜索过程,在获取get_peer请求时进行递归get_peer请求,注意控制深度。可以扩大K-bucket桶的大小,降低二叉树的深度。
  6.在使用peer wire protocol过程中,因为运营商对P2P封锁,很多情况下下载种子失败,可以使用知名种子库进行info-hash下载。
  7.注意控制udp发包速度,以免被主机商防火墙误以为中毒。
  PT
  额外提一点,关于现在的PT,PT网络是禁止开启DHT,防止资源外泄。在PT站发布的种子都会包含PT站的私有tracker服务地址,每个会员下载的种子也会包含自己的私有token,当种子泄露到BT上时,PT管理员很容易封禁掉该会员的信息。PT致力于打造高端高活跃的P2P分享网络。
  参考资料
  http://www.cs.rice.edu/Conferences/IPTPS02/109.pdf
  http://www.bittorrent.org/beps/bep_0005.html
  http://www.bittorrent.org/beps/bep_0003.html
  http://www.bittorrent.org/beps/bep_0000.html
  http://www.bittorrent.org/beps/bep_0009.html
  https://wiki.theory.org/index.php/
  作者:戚华威
  来源:微信公众号:讯飞技术沙龙
  出处:https://mp.weixin.qq.com/s/Y1hMesi54glenNt7n_UCiw

为备战亚洲杯亚运会,国家队集训名单今日出炉为备战2023年女篮亚洲杯亚运会等重要赛事,中国篮球协会拟组织国家女篮于2023年3月30日5月24日在清远新世纪篮球训练基地进行集训选拔。今日发布了主教练麾下的集训女篮名单,其中为什么知乎经常搬运其他网站的问题?根据介绍,知乎是一个中文互联网高质量的问答社区和创作者聚集的原创内容平台,于2011年1月正式上线,以让人们更好地分享知识经验和见解,找到自己的解答为品牌使命。但知乎最近大量出现很2023年长春市农村电商实用型培训提升班开班,进一步提升农村电子商务运用能力为进一步提升农村电子商务运用能力,普及农产品网络销售知识与技能,3月1日,2023年长春市农村电商实用型培训提升班在会展中心举办。本次活动由长春市农业农村局长春市商务局联合主办,吉雨雪润春花美乍暖还寒的春日里,盛开的花朵在雨雪浸润下显得更加娇美。2023年3月16日,河南省沁阳市滨河公园,市民在观赏雪中梅花。CICPHOTO杨帆摄2023年3月16日在湖北省十堰市郧阳区杨太真外传卷下(一)当初,在开元末年,江陵进献乳柑桔,玄宗把十枚种在蓬莱宫,到天宝十年九月秋,结出了果实。玄宗宣旨将它们赏赐给宰臣,说朕近年来在宫内种柑子树数株,今秋结下果实一百五十多颗,与江南及蜀地180斤大码超模又带黑人老公走红毯!性感内衣外披层红纱,真敢穿最近这些年,因为经济文化的增长,人们的思想也是越来越开放,就连向来苛刻的时尚圈都显得更为包容,涌现了一大批非常优秀的大码模特,这些大码超模们用自信来展现时装的美丽,同时也完美的证明逆势增长!一加实现品牌增速第一,努力做好品质和服务成首要目标文手机技巧库近年来,手机行业开始进入存量市场,产品出货量遭遇瓶颈期。一方面消费者用机周期变长,另一方面由于换机需求降低,各家手机厂商都不好过。即使是高端手机市场几乎一枝独秀的苹果,顺着2亿玩家的心思做游戏,明日之后有多宠玩家?按照常理来说,游戏玩家与游戏策划并不是一条心,游戏玩家想自个玩得更爽一点,而游戏策划则在想如何噶玩家的韭菜。游戏玩家很少会去说策划的好话,游戏策划也很难真正理解玩家到底想要什么。可千年手游二层版本教学第二期当游戏内二层版本开放的时候我们就可以购买二层功法,但是没有玩过这款游戏的小伙伴会发现购买了之后不能学,这是因为我们没有学习对应的一层功法,一层功法与二层功法之间是有对应关系的,就相千年古城崭露头角!济南,这样乘上网红的快车春节过后,济南在成为网红城市的道路上一路狂飙,趵突泉超然楼芙蓉街济南国际双年展这些关键词刷新着各个社交平台,展现着济南这座千年古城的独特魅力。济南将着力寻求突破,以打造强新优富美高宝可梦朱紫玩家正在用BUG飞向宇宙去年宝可梦朱紫发售之际,玩家社区里讨论度最高的话题不是新增的宝可梦,也并非全新的对战环境,而是收集与分享游戏内那些千奇百怪神秘莫测的BUG。相信体验过宝可梦朱紫1。0版本的玩家如今
如果同时考上了武汉和北京的985大学,去哪个城市比较好呢?论读书的城市当然是北京好,但是也得看你考的分数,再想想你需要读什么专业,最后才确定读什么大学。首先,我们来看看北京和武汉都有哪些985高校北京的985高校有8所清华大学北京大学中国什么事是去了驻马店才知道的?驻马店李新店人民生活过得的非常滋润,明港镇人民更是非常富裕,在明港镇待了五年的我,才知道真正的原因,现在我相信生活会更加完美。十年前我就在李新店飞机场当兵对那里的一切基本了如指掌,美术类的学生为什么最后大多选择做设计?你好,对于为什么美术类的考生,最好大多选择做设计专业这个问题,我来回答你,首先我们要知道,美术类的专业有哪些?我大概的列举一些专业1绘画类的专业有国画书法雕塑油画美教等。2设计类的一个月扣除五险一金后,到手3000元左右的人有多少?这样的工作该不该继续干下去呢?打卡三千左右者十之四五。这已经让很多人望尘莫及了!珍惜吧!以我熟悉的教师职业来说,目前,刚刚入职的大专或者本科学历教师的打卡工资不低于2500元,教龄在15年以下者,没有晋级中级职成都三甲医院有哪些?位于成都市的三甲医院总共有30家,分别位于青羊区9家,锦江区4家,金牛区4家,武侯区10家,新都区1家,温江区2家,接下来就给大家详细说明这30家三甲医院分别是那30家医院。青羊区湖北医药学院怎么样?湖北医药学院坐落于湖北省十堰市,始建于1965年,于1977年开始普通本科教育,1994年经原国家教委批准,正式列入国家普通高校序列,并定名为郧阳医学院。2010年经国家教育部批准哈工大威海校区怎么样?近三年录取分数线是多少?哈工大(威海)是哈工大一校三区办学格局的重要组成部分。1985年,经原航天工业部批准,哈尔滨工业大学威海分校成立,2002年正式更名为哈尔滨工业大学(威海),即哈工大威海校区。20湖北广水市能成为地级市吗?除非和大悟合并,成立广悟市,要不然不太可能,广水跟大悟地理位置很好,境内有107国道,京广铁路,京珠高速,京广高铁,交通便利,以后广水镇跟大悟城区融城可能会成立新的地级市,毕竟武汉哪些财经类高校比较牛?财经类院校一直备受关注,高考录取分数也较高。在中国财经类高校群体中,两财一贸(即上海财经大学中央财经大学和对外经济贸易大学)是的知识度是最大的。除了这些知名财经高校,中国还有哪些财入侵澳大利亚的仙人掌,花24亿也消灭不了,为何败给了一群蛾子?澳大利亚是个神奇的地方,似乎各种生物到了澳大利亚,用不了多长时间就会泛滥,除了兔子跟骆驼,像是狐狸野狗小龙虾蟾蜍之类的例子非常之多。比起动物,在澳大利亚泛滥的外来植物比较少见,而仙如果不小心在分班考试时考了高分,进了一个全是学霸的实验班怎么办?能考入学霸实验班证明你有真正的较强的学习力!恭喜你,祝贺你!学霸实验班的学习氛围浓厚,相信自己,你能行!做好以下几点,学霸非你莫属!一相信自己,这是学习的动力。柏拉图说只要相信自己