def call(self): ''' Call the function, passing self.arguments. Use self.cookie for auth if provided. ''' password = self.client.password txid = random_string() pass_hash = hashlib.sha256(password + self.cookie).hexdigest() req = { 'q': 'auth', 'aq': self.function_name, 'hash': pass_hash, 'cookie': self.cookie, 'args': self.call_args, 'txid': txid } first_time_benc_req = bencoder.encode(req) req['hash'] = hashlib.sha256(first_time_benc_req).hexdigest() second_time_benc_req = bencoder.encode(req) if SUPER_VERBOSE: print "Calling function: %s" % req self.send(second_time_benc_req) return txid
def call(self): """ Call the function, passing self.arguments. Use self.cookie for auth if provided. """ password = self.client.password txid = random_string() pass_hash = hashlib.sha256(password + self.cookie).hexdigest() req = { "q": "auth", "aq": self.function_name, "hash": pass_hash, "cookie": self.cookie, "args": self.call_args, "txid": txid, } first_time_benc_req = bencoder.encode(req) req["hash"] = hashlib.sha256(first_time_benc_req).hexdigest() second_time_benc_req = bencoder.encode(req) if SUPER_VERBOSE: print "Calling function: %s" % req self.send(second_time_benc_req) return txid
def gen_hash(): ''' Generated SHA1 hash based on the 'info' section of the magnet link data. ''' info = magnet.info encoded_info = bencoder.encode(info) return hashlib.sha1(encoded_info)
def get_peer_id(self): info = encode(self.torrent_file_dict[b'info']) peer_id = 'SA' + ''.join( random.choice(string.ascii_lowercase + string.digits) for i in range(18) ) return peer_id
def gen_hash(torrent_dat): ''' Generated SHA1 hash based on the 'info' section of the magnet link data. ''' info = torrent_dat['info'] encoded_info = bencoder.encode(info) return hashlib.sha1(encoded_info)
def add_trcackers(filename): f = open('torrent/' + filename, "rb") # 读入文件 d = bencoder.decode(f.read()) #print(d[b'announce-list']) trackers = 'track.txt' # 保存trackers的文本文档,可编辑,可自行添加trackers track_list = [] with open(trackers) as f: for line in f: if len(line) > 1: l = line.rstrip() n = [] n.append(l) track_list.append(n) #print(000, len(track_list)) #print(len(track_list)) a = track_list + d[b'announce-list'] l2 = [] for i in a: if i not in l2: l2.append(i) print(len(l2)) d[b'announce-list'] = l2 with open('torrent/' + filename, "wb") as n: n.write(bencoder.encode(d)) # 写入文件 print('共', len(d[b'announce-list']), '个trackers.')
def get_cookie(self, txid=None): if not txid: txid = random_string() request = {'q': 'cookie', 'txid': txid} self.transport.write(bencoder.encode(request), (self.host, self.port)) return txid
def ping(self): """ Pings the CJDNS Admin API for this node, ensuring it is up. If no pong is received within 1 second, try again. """ ping = bencoder.encode(self.actions["ping"]) reactor.callLater(1, self.check_ponged) self.transport.write(ping, (self.host, self.port))
def ping(self): ''' Pings the CJDNS Admin API for this node, ensuring it is up. If no pong is received within 1 second, try again. ''' ping = bencoder.encode(self.actions['ping']) reactor.callLater(1, self.check_ponged) self.transport.write(ping, (self.host, self.port))
def ask_for_functions(self, page): availableFunctions = {} request_dict = { 'q': 'Admin_availableFunctions', 'args': { 'page': page } } self.transport.write(bencoder.encode(request_dict), (self.host, self.port))
def _send_error(self, code, msg, ip, port): transaction_id = self._generate_transaction_id() if isinstance(msg, str): msg = msg.encode('utf-8') payload = { b't': b'E' + transaction_id, b'y': b'e', b'e': [code, msg], } self.transport.sendto(bencoder.encode(payload), (ip, port)) return transaction_id
def request_cookie(self): """ Obtain a cookie """ txid = random_string() request = {"q": "cookie", "txid": txid} self.send(bencoder.encode(request)) if SUPER_VERBOSE: print "requested cookie for to run %s as %s" % (self.function_name, txid) return txid
def send_krpc(self, msg, address): """ 发送 krpc 协议 :param msg: 发送 UDP 报文信息 :param address: 发送地址,(ip, port) 元组 """ try: # msg 要经过 bencode 编码 self.udp.sendto(bencoder.encode(msg), address) except: pass
def _send_ping(self, ip, port): transaction_id = self._generate_transaction_id() payload = { b't': transaction_id, b'y': b'q', b'q': b'ping', b'a': { b'id': self.packed_id }, } self.transport.sendto(bencoder.encode(payload), (ip, port)) return transaction_id
def feed_datagram(self, data, addr): """called when received a UDP datagram""" ip, port = addr try: msg = bencoder.decode(data) except: raise BadDHTMessageError('not properly bencoded') try: transaction_id = msg[b't'] message_type = msg[b'y'] except KeyError: raise BadDHTMessageError('bad dict') if message_type == b'q': # received a query query_type = msg.get(b'q') arg = msg.get(b'a') if not query_type or not arg: raise BadDHTMessageError('bad query') method = self._query_handler_method_map.get(query_type) if not method: raise BadDHTMessageError('unknown query type') response = method(arg, ip, port) if not response: return payload = { b't': transaction_id, b'y': b'r', b'r': response, } self.transport.sendto(bencoder.encode(payload), addr) remote_id = arg.get(b'id') if remote_id is not None: self._update_kbucket(decode_id(remote_id), ip, port) elif message_type == b'r': # received a response arg = msg.get(b'r') if not arg: raise BadDHTMessageError('bad response') future_key = (ip, port, transaction_id) future = self._query_future_map.get(future_key) if not future: raise BadDHTMessageError('response without query') del self._query_future_map[future_key] future.set_result(arg) remote_id = arg.get(b'id') if remote_id is not None: self._update_kbucket(decode_id(remote_id), ip, port) else: raise BadDHTMessageError('unknown message type')
def request_cookie(self): ''' Obtain a cookie ''' txid = random_string() request = {'q': 'cookie', 'txid': txid} self.send(bencoder.encode(request)) if SUPER_VERBOSE: print "requested cookie for to run %s as %s" % (self.function_name, txid) return txid
def _send_get_peers(self, info_hash, ip, port): transaction_id = self._generate_transaction_id() payload = { b't': transaction_id, b'y': b'q', b'q': b'get_peers', b'a': { b'id': self.packed_id, b'info_hash': encode_id(info_hash), }, } self.transport.sendto(bencoder.encode(payload), (ip, port)) return transaction_id
def _send_find_node(self, id, ip, port): transaction_id = self._generate_transaction_id() payload = { b't': transaction_id, b'y': b'q', b'q': b'find_node', b'a': { b'id': self.packed_id, b'target': encode_id(id), }, } self.transport.sendto(bencoder.encode(payload), (ip, port)) return transaction_id
async def _add_torrent_url(self, url, options): async with self.core.session.get(url) as response: body = await response.read() parsed_body = bencoder.decode(body) info_hash = hashlib.sha1(bencoder.encode( parsed_body[b'info'])).hexdigest() await self._client.call_remote( 'core.add_torrent_file', parsed_body[b'info'][b'name'] + b'.torrent', base64.b64encode(body), options, ) return info_hash
def call_function(self, cookie, function_name, call_args, txid=None, password=None): if not password: password=self.password if not txid: txid = random_string() pass_hash = hashlib.sha256(password + cookie).hexdigest() req = { 'q': 'auth', 'aq': function_name, 'hash': pass_hash, 'cookie': cookie, 'args': call_args, 'txid': txid } first_time_benc_req = bencoder.encode(req) req['hash'] = hashlib.sha256(first_time_benc_req).hexdigest() second_time_benc_req = bencoder.encode(req) if SUPER_VERBOSE: print "Calling function: %s" % req self.transport.write(second_time_benc_req, (self.host, self.port))
def parse_torrent_input(torrent, walk=True, recursive=False): # torrent is literal infohash if re.match(r'^[\da-fA-F]{40}$', torrent): return {'hash': torrent} # torrent is literal id if re.match(r'^\d+$', torrent): return {'id': torrent} # torrent is valid path if os.path.exists(torrent): if walk and os.path.isdir(torrent): for path in map(lambda x: os.path.join(torrent, x), os.listdir(torrent)): handle_input_torrent(path, recursive, recursive) return 'walked' # If file/dir name is info hash use that filename = os.path.split(torrent)[-1].split('.')[0] if re.match(r'^[\da-fA-F]{40}$', filename): return {'hash': filename} # If torrent file compute the info hash if not args.no_hash and os.path.isfile(torrent) and os.path.split( torrent)[-1].endswith('.torrent'): global encode, decode if 'encode' not in globals() or 'decode' not in globals(): try: from bencoder import encode, decode except: print( 'Found torrent file ' + torrent + ' but unable to load bencoder module to compute hash') print( 'Install bencoder (pip install bencoder) then try again or pass --no-hash to not compute the hash' ) if args.ignore_invalid: return None else: sys.exit(EXIT_CODES['input-error']) with open(torrent, 'rb') as torrent: try: decoded = decode(torrent.read()) info_hash = sha1(encode(decoded[b'info'])).hexdigest() except: return None return {'hash': info_hash} # torrent is a URL url_match = re.match(r'.*torrentid=(\d+).*', torrent) if not url_match or url_match.lastindex < 1: return None return {'id': url_match[1]}
def _send_announce_peer(self, info_hash, token, ip, port, downloader_port): transaction_id = self._generate_transaction_id() payload = { b't': transaction_id, b'y': b'q', b'q': b'announce_peer', b'a': { b'id': self.packed_id, b'info_hash': encode_id(info_hash), b'token': token, b'port': downloader_port, b'implied_port': ANNOUNCE_IMPLIED_PORT, }, } self.transport.sendto(bencoder.encode(payload), (ip, port)) return transaction_id
def __init__(self, file_name): self.file_name = file_name self.peerID = self.construct_peer_id() self.downloaded = 0 self.uploaded = 0 self.compact = 1 # TODO: proper handling of port. From 6881-6889 check every port if it is open and pick the first one self.port = 6882 # self.event = 'started' if file_name.endswith('torrent'): file = open(file_name, 'rb') self.torrent_data = bencoder.decode(file.read()) self.info = self.torrent_data[b'info'] self.hash_info = hashlib.sha1(bencoder.encode(self.info)).digest() self.creation_date = self.torrent_data[b'creation date'] self.announce_list = list() if b'announce_list' in self.torrent_data.keys(): self.announce_list = self.torrent_data[b'announce-list'] elif b'httpseeds' in self.torrent_data.keys(): self.announce_list = self.torrent_data[b'httpseeds'] self.announce_list.append(self.torrent_data[b'announce']) if b'files' in self.info.keys(): self.files = self.info[b'files'] else: # In case we have only one file we change it to a similar format as multi file torrent self.files = list() file_data = dict() file_data[b'length'] = self.info[b'length'] file_data[b'path'] = list() file_data[b'path'].append(self.info[b'name']) self.files.append(file_data) self.total_length = self.get_total_length() elif file_name.startswith('magnet'): self.torrent_data = self.magnet_to_torrent(file_name) self.hash_info = self.torrent_data[b'info'][b'hash_info'] self.announce_list = self.torrent_data[b'announce-list'] self.announce_list.append(self.torrent_data[b'announce'])
def __init__(self, path_to_torrent, peer_id): # Set id self.peer_id = peer_id # Read torrent file with open(path_to_torrent, 'rb') as torrent_file: torrent_contents = torrent_file.read() # Decode torrent file self.metainfo = decode(torrent_contents) # Get info dictionary self.info_dict = self.metainfo[b'info'] # Create SHA1 hash of info dictionary hash_sha1 = hashlib.sha1() hash_sha1.update(encode(self.info_dict)) self.info_hash = hash_sha1.digest() # Get announce url self.announce_url = self.metainfo[b'announce'] # Get pieces and pieces length self.piece_length = self.info_dict[b'piece length'] self.pieces = self.info_dict[b'pieces'] # Get name of the torrent self.torrent_name = self.info_dict[b'name'] # Get the length of the torrent and determine if it's a multi file torrent if b"files" in self.info_dict.keys(): total_length = 0 for i in self.info_dict[b'files']: total_length += i[b'length'] self.torrent_length = total_length self.is_multi_files = True else: self.torrent_length = self.info_dict[b'length'] self.is_multi_files = False # get paths for each file if its a multi file torrent if self.is_multi_files: self.file_paths = [] for i in self.info_dict[b'files']: self.file_paths.append([i[b'path'], i[b'length']])
def __init__(self, file_name): # Text self._bencoded_text = read_binary_file(file_name) self._parsed_text = bencoder.decode(self._bencoded_text)[0] self._parsed_info_hash = self._parsed_text['info'] self.bencoded_info_hash = bencoder.encode(self._parsed_info_hash) # turn into readonly property # File information self.file_info_dict = self._get_file_info_dict() self.base_file_name = self._parsed_info_hash['name'] self.type = "single" if len(self.file_info_dict.keys()) == 1 else "multiple" # Length and piece information self.total_length = self._get_total_length() self.piece_length = self._parsed_info_hash['piece length'] self.num_pieces = int(len(self._parsed_info_hash['pieces']) / 20) self.request_blocks_per_piece = int(math.ceil( float(self.piece_length) / 2**14)) self.pieces_hash = self._parsed_info_hash['pieces']
def get_download_info(cls, dictionary): info_hash = hashlib.sha1(bencoder.encode(dictionary)).digest() if len(dictionary[b'pieces']) % SHA1_DIGEST_LEN != 0: raise ValueError('Invalid length of "pieces" string') piece_hashes = grouper(dictionary[b'pieces'], SHA1_DIGEST_LEN) if b'files' in dictionary: files = list(map(FileInfo.get_info, dictionary[b'files'])) else: files = [FileInfo.get_info(dictionary)] return cls(info_hash, dictionary[b'piece length'], piece_hashes, dictionary[b'name'].decode(), files, private=dictionary.get('private', False))
def getinfo(self, filename): fp = open(filename, "rb") data = fp.read() #it is string #print data decode_data = bencoder.decode(data) #get a dictionary #print(decode_data) if 'announce' in decode_data and 'info' in decode_data: self.tracker = decode_data.get('announce') self.tracker_list = decode_data.get('announce-list') self.create = decode_data.get('created by') self.date = decode_data.get('creation date') self.source = decode_data.get('comment') info = decode_data.get('info') self.piece_size = info.get('piece length') self.pieces = info.get('pieces') else: #print("Invalid torrent file") pass if 'length' in info: self.directory = '' self.files = [(info.get('name'), info.get('length'))] self.size = info.get('length') self.name = info.get('name') else: files = [] self.directory = info.get('name') for d in decode_data['info']['files']: files.append((d['path'], d['length'])) self.size += d['length'] if self.size % self.piece_size != 0: extra = 1 # print 'extra 1' else: extra = 0 # print 'extra 2' self.no_of_pieces = self.size / self.piece_size + extra # print self.no_of_pieces sha1 = hashlib.sha1() sha1.update(bencoder.encode(info)) self.hash_info = sha1.digest()
def __init__(self, file_name): # Text self._bencoded_text = message.read_binary_file(file_name) self._parsed_text = bencoder.decode(self._bencoded_text)[0] self._parsed_info_hash = self._parsed_text['info'] self.bencoded_info_hash = bencoder.encode( self._parsed_info_hash) # turn into readonly property # File information self.file_info_dict = self._get_file_info_dict() self.base_file_name = self._parsed_info_hash['name'] self.type = "single" if len( self.file_info_dict.keys()) == 1 else "multiple" # Length and piece information self.total_length = self._get_total_length() self.piece_length = self._parsed_info_hash['piece length'] self.num_pieces = int(len(self._parsed_info_hash['pieces']) / 20) self.request_blocks_per_piece = int( math.ceil(float(self.piece_length) / POLITE_REQUEST_SIZE)) self.pieces_hash = self._parsed_info_hash['pieces']
def test_it_encodes_dicts_w_nums_and_lists(self): encoded_dict = bencoder.encode(OrderedDict([('length', 291), ('path', ['Distributed by Mininova.txt'])])) self.assertEqual(encoded_dict, self.dict_w_nums_and_lists)
def test_it_encodes_nested_lists(self): encoded_list = bencoder.encode([['spam', 'eggs'], ['spam', 'eggs']]) self.assertEqual(encoded_list, self.b_nested_list)
def test_it_encodes_single_item_lists(self): encoded_list = bencoder.encode(['Distributed by Mininova.txt']) self.assertEqual(encoded_list, self.b_single_word_list)
def test_reversing_walden(self): t = metainfo.MetainfoFile(self.walden) encoded_torrent = bencoder.encode(t._parsed_text) self.assertEqual(t.bencoded_text, encoded_torrent)
def test_reversing_comic(self): t = metainfo.MetainfoFile(self.comics) encoded_torrent = bencoder.encode(t._parsed_text) self.assertEqual(t._bencoded_text, encoded_torrent)
def ask_for_functions(self, page): availableFunctions = {} request_dict = {"q": "Admin_availableFunctions", "args": {"page": page}} self.transport.write(bencoder.encode(request_dict), (self.host, self.port))
def ask_for_functions(self, page): availableFunctions = {} request_dict = {'q': 'Admin_availableFunctions', 'args': {'page': page}} self.transport.write(bencoder.encode(request_dict), (self.host, self.port))
def test_it_encodes_a_dict_with_list_values(self): encoded_dict = bencoder.encode(OrderedDict([('spam', ['a', 'b']), ('eggs', ['a', 'b'])])) self.assertEqual(encoded_dict, self.dict_w_lists)
def test_it_encodes_a_bigger_dict(self): encoded_dict = bencoder.encode(OrderedDict([('publisher', 'bob'), ('publisher-webpage', 'www.example.com'), ('publisher.location', 'home')])) self.assertEqual(encoded_dict, self.bigger_b_dict)
def test_it_decodes_a_dict_of_strings(self): encoded_dict = bencoder.encode(OrderedDict([('cow', 'moo'), ('spam', 'eggs')])) self.assertEqual(encoded_dict, self.little_b_dict)
def _infohash(metadata): sha1 = hashlib.sha1() info = bencoder.encode(metadata[b'info']) sha1.update(info) return sha1.hexdigest()
def test_it_encodes_nested_lists(self): encoded_list = bencoder.encode([['spam', 'eggs'], ['spam', 'eggs']]) self.assertEqual(encoded_list, self.b_nested_list)
def test_it_encodes_single_item_lists(self): encoded_list = bencoder.encode(['Distributed by Mininova.txt']) self.assertEqual(encoded_list, self.b_single_word_list)
def test_reversing_walden(self): t = metainfo.MetainfoFile(self.walden) encoded_torrent = bencoder.encode(t._parsed_text) self.assertEqual(t._bencoded_text, encoded_torrent)
def test_encoding_dictionary(self): expected = b'd2:doli1e1:ce3:how2:do3:youi42ee' result = encode({b'how': b'do', b'you': 42, b'do': [1, b'c']}) self.assertEqual(expected, result)
def ping(self): print "Pinging." ping = bencoder.encode(self.actions['ping']) reactor.callLater(1, self.check_ponged) self.transport.write(ping, (self.host, self.port))
def test_it_encodes_dicts_w_some_numbers(self): encoded_dict = bencoder.encode(OrderedDict([('bar', 'spam'), ('foo', 42)])) self.assertEqual(encoded_dict, self.dict_w_nums)
def get_info_hash(self): info = encode(self.torrent_file_dict[b'info']) return hashlib.sha1(info).digest()
def test_it_encodes_dicts_w_nums_and_lists(self): encoded_dict = bencoder.encode(OrderedDict([('length', 291), ('path', ['Distributed by Mininova.txt'])])) self.assertEqual(encoded_dict, self.dict_w_nums_and_lists)
def test_it_encodes_actual_bittorrent_files(self): decoded_dict = bencoder.decode(self.metainfo_file)[0] encoded_file = bencoder.encode(decoded_dict) self.assertEqual(self.metainfo_file, encoded_file)
def test_it_encodes_actual_bittorrent_files(self): decoded_dict = bencoder.decode(self.metainfo_file)[0] encoded_file = bencoder.encode(decoded_dict) self.assertEqual(self.metainfo_file, encoded_file)
def test_encoding_list(self): expected = b'li1eli2eli3eeee' result = encode([1, [2, [3]]]) self.assertEqual(expected, result)
def test_it_encodes_dicts_w_some_numbers(self): encoded_dict = bencoder.encode(OrderedDict([('bar', 'spam'), ('foo', 42)])) self.assertEqual(encoded_dict, self.dict_w_nums)