2015-05-19 2 views
5

Использование «повторно» я скомпилировать ДАННЫЕ рукопожатия, как это:Как взять элемент после re.compile?

piece_request_handshake = re.compile('13426974546f7272656e742070726f746f636f6c(?P<reserved>\w{16})(?P<info_hash>\w{40})(?P<peer_id>\w{40})') 

handshake = piece_request_handshake.findall(hex_data) 

Тогда я распечатать его

Я не могу добавить изображение, потому что я новичок так это выход:

[email protected]:/home/florian/Téléchargements# python script.py 
[('0000000000100005', '606d4759c464c8fd0d4a5d8fc7a223ed70d31d7b', '2d5452323532302d746d6e6a657a307a6d687932')] 

Мой вопрос, как я могу взять только Secon d часть этих данных, то есть «hash_info» («606d47 ...»)?

Я уже пытался с группой повторно с помощью следующей строки:

print handshake.group('info_hash') 

Но результат ошибки (извините еще раз я не могу показать экран ...):

*[email protected]:/home/florian/Téléchargements# python script.py 
Exception in thread Thread-1: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner 
    self.run() 
    File "script.py", line 122, in run 
    self.p.dispatch(0, PieceRequestSniffer.cb) 
    File "script.py", line 82, in cb 
    print handshake.group('info_hash') 
AttributeError: 'list' object has no attribute 'group'* 

Это начало моего полного кода для любознательных:

import pcapy 
import dpkt 
from threading import Thread 
import re 
import binascii 
import socket 
import time 

liste=[] 
prefix = '13426974546f7272656e742070726f746f636f6c' 
hash_code = re.compile('%s(?P<reserved>\w{16})(?P<info_hash>\w{40})(?P<peer_id>\w{40})' % prefix) 
match = hash_code.match() 
piece_request_handshake = re.compile('13426974546f7272656e742070726f746f636f6c(?P<aaa>\w{16})(?P<bbb>\w{40})(?P<ccc>\w{40})') 
piece_request_tcpclose = re.compile('(?P<start>\w{12})5011') 


#-----------------------------------------------------------------INIT------------------------------------------------------------ 

class PieceRequestSniffer(Thread): 
    def __init__(self, dev='eth0'): 
     Thread.__init__(self) 

     self.expr = 'udp or tcp' 

     self.maxlen = 65535 # max size of packet to capture 
     self.promiscuous = 1 # promiscuous mode? 
     self.read_timeout = 100 # in milliseconds 
     self.max_pkts = -1 # number of packets to capture; -1 => no limit 

     self.active = True 
     self.p = pcapy.open_live(dev, self.maxlen, self.promiscuous, self.read_timeout) 
     self.p.setfilter(self.expr) 

    @staticmethod 
    def cb(hdr, data): 

     eth = dpkt.ethernet.Ethernet(str(data)) 
     ip = eth.data 



#------------------------------------------------------IPV4 AND TCP PACKETS ONLY---------------------------------------------------   



      #Select Ipv4 packets because of problem with the .p in Ipv6 
     if eth.type == dpkt.ethernet.ETH_TYPE_IP6: 
      return 
     else: 

      #Select only TCP protocols 
      if ip.p == dpkt.ip.IP_PROTO_TCP: 
       tcp = ip.data 

       src_ip = socket.inet_ntoa(ip.src) 
       dst_ip = socket.inet_ntoa(ip.dst) 

       fin_flag = (tcp.flags & dpkt.tcp.TH_FIN) != 0 
       #if fin_flag: 
        #print "TH_FIN src:%s dst:%s" % (src_ip,dst_ip) 




       try: 
        #Return hexadecimal representation 
        hex_data = binascii.hexlify(tcp.data) 
       except: 
        return 



#-----------------------------------------------------------HANDSHAKE------------------------------------------------------------- 




       handshake = piece_request_handshake.findall(hex_data) 
       if handshake and (src_ip+" "+dst_ip) not in liste and (dst_ip+" "+src_ip) not in liste and handshake != '': 
        liste.append(src_ip+" "+dst_ip) 
        print match.group('info_hash') 
+5

Добро пожаловать в Stack Overflow (и остальную часть сети обмена файлами)! Вы вопрос на самом деле лучше без скриншотов, так как вывод программ командной строки является простым текстом. К сожалению, я не знаю ответа, но я подумал, что это был [очень хороший вопрос] (http://stackoverflow.com/help/how-to-ask) от первого пользователя, и он заслужил до-голосования. –

ответ

4

re.findall() возвращает список кортежей, каждый из которых содержит соответствующие строки, соответствующие названным группам в шаблоне re. Этот пример (используя упрощенный рисунок) показывает, что вы можете получить доступ к необходимому элементу с индексацией:

import re 

prefix = 'prefix' 
pattern = re.compile('%s(?P<reserved>\w{4})(?P<info_hash>\w{10})(?P<peer_id>\w{10})' % prefix) 
handshake = 'prefix12341234567890ABCDEF1234' # sniffed data 
match = pattern.findall(handshake) 

>>> print match 
[('1234', '1234567890', 'ABCDEF1234')] 
>>> info_hash = match[0][1] 
>>> print info_hash 
1234567890 

Но суть названных групп, чтобы обеспечить возможность доступа совпавших значений для имени группы по имени. Вы можете использовать re.match() вместо:

import re 

prefix = 'prefix' 
pattern = re.compile('%s(?P<reserved>\w{4})(?P<info_hash>\w{10})(?P<peer_id>\w{10})' % prefix) 
handshake = 'prefix12341234567890ABCDEF1234' # sniffed data 
match = pattern.match(handshake) 

>>> print match 
<_sre.SRE_Match object at 0x7fc201efe918> 
>>> print match.group('reserved') 
1234 
>>> print match.group('info_hash') 
1234567890 
>>> print match.group('peer_id') 
ABCDEF1234 

Значение также доступно с помощью словаря доступ:

>>> d = match.groupdict() 
>>> d 
{'peer_id': 'ABCDEF1234', 'reserved': '1234', 'info_hash': '1234567890'} 
>>> d['info_hash'] 
'1234567890' 

Наконец, если существует несколько последовательностей квитирования во входных данных, вы можете использовать re.finditer():

import re 

prefix = 'prefix' 
pattern = re.compile('%s(?P<reserved>\w{4})(?P<info_hash>\w{10})(?P<peer_id>\w{10})' % prefix) 
handshake = 'blahprefix12341234567890ABCDEF1234|randomjunkprefixABCDEF1234,more random junkprefix1234hellothereABCDEF1234...' # sniffed data 

for match in pattern.finditer(handshake): 
    print match.group('info_hash') 

Выход:

 
1234567890 

hellothere 
+0

Спасибо за ваше время и ваш очень хороший ответ @mhawke, на самом деле pattern.match, похоже, ставит известную информацию, проблема в том, что i не знаю данных в рукопожатии, и я попробовал pattern.match (рукопожатие) с рукопожатием как моя переменная со всеми данными, но он выдает ошибку, потому что соответствие ожидает строку:/ – flo

+0

'handshake' - это список, чтобы вы могли 't передать это 're.match()'. Что касается «известных данных», значит, вы не знаете префикс '13426974546f7272656e742070726f746f636f6c' в вашем примере? – mhawke

+0

Я имею в виду, что на самом деле мой код - это своего рода рукотворный сниффер, префикс '13426974546f7272656e742070726f746f636f6c' является общим для всех рукопожатий и позволяет их распознавать. Он будет там все время, поскольку я действую только тогда, когда пакет является рукопожатием. Однако изменение хэша, каждый торрент и идентификатор peer после хэша почти никогда не совпадают. Что касается этой проблемы, я использую переменную, которая содержит данные подтверждения, пока другое рукопожатие не предоставит ей свои данные. @mhawke – flo

1

re.findall вернет список кортежей. group() вызов работает на Match объектов, возвращенных некоторыми другими функциями в re:

for match in re.finditer(needle, haystack): 
    print match.group('info_hash') 

Кроме того, вы, возможно, не потребуется findall, если вы просто соответствие один рукопожатия.

+0

На самом деле re.findall() возвращает список кортежей, содержащих соответствующие группы. – mhawke

+0

Ах, как плохо, кажется, ты прав. Боюсь, я слишком быстро сообразил, что все в 're' предоставляет объекты' Match' ... – akaIDIOT

Смежные вопросы