2016-01-18 2 views
6

Я имею 3 словарей в моем питона код:Как сравнить словари и посмотреть, что изменилось?

  1. self.new_port_dict = {} # Словарь хранить новые порты из curr_host
  2. self.old_port_dict = {} # Словарь хранить старые порты из old_host
  3. self.results_ports_dict = {} # Удерживает результат измененных/вновь добавленных портов

Сценарий должен сравнить, какой порт был изменен, я почти там просто не могу помочь мне помочь :

 def comp_ports(self,filename): 
      try: 
       f = open(filename) 
       self.prev_report = pickle.load(f) # NmapReport 

       for s in self.prev_report.hosts: 
        self.old_port_dict[s.address] = set() 
        for x in s.get_open_ports(): 
         self.old_port_dict[s.address].add(x) 

       for s in self.report.hosts: 
        self.new_port_dict[s.address] = set() 
        for x in s.get_open_ports(): 
         self.new_port_dict[s.address].add(x) 

       print "The following Host/ports were available in old scan : !!" 
       print `self.old_port_dict` 
       print "--------------------------------------------------------" 
       print "The following Host/ports have been added in new scan: !!" 
       print `self.new_port_dict` 
       for h in self.old_port_dict.keys(): 
       self.results_ports_dict[h] = self.new_port_dict[h]- self.old_port_dict[h] 
       print "Result Change: for",h ,"->",self.results_ports_dict[h]   

except Exception as l: 
      print l 

Это дает результат, как:

The following Host/ports were available in old scan : !! 
{'172.16.0.41': set([(80, 'tcp'), (666, 'tcp')]), '172.16.0.163': set([(80, 'tcp'), (22, 'tcp')])} 
-------------------------------------------------------- 
The following Host/ports have been added in new scan: !! 
{'172.16.0.41': set([(80, 'tcp'), (22, 'tcp')]), '172.16.0.163': set([(80, 'tcp'), (22, 'tcp')])} 

Result Change: for 172.16.0.41 -> set([(22, 'tcp')]) From set([(80, 'tcp'), (666, 'tcp')]) 

Result Change: for 172.16.0.163 -> set([]) From set([(80, 'tcp'), (22, 'tcp')]) 

Как вы можете ясно видеть, я образовавшееся изменил словарь, а также. Я хочу просто напечатать:

For "host_name" , Port changed from "port_id" to "new_port_id" 

ex: For 172.16.0.41, Port changed from (666, 'tcp') to (22, 'tcp') 
+0

Я думаю, что конец коды отсутствует – CoMartel

ответ

1

Я считаю, что вы не сравниваете словари, но фактически значения, соответствующие ключам.

основных идей здесь:

  • Хост не должен всегда присутствовать в прошлом и настоящие сканирование и HANCE использования collections.defaultdict, чтобы обеспечить прямое сравнение значений даже в отсутствии хозяина , Поскольку значение для пропавших ключа будет автоматически генерируются (пустой set)

  • Есть 3 операции на set портов

    • & (пересечение): чтобы увидеть, какие порты остаются неизменными через сканирование (те же порты)

    • old - new: чтобы увидеть, какие порты были в старом сканирования, но уже не в новых (удаленные порты)

    • new - old: чтобы увидеть, какие порты находятся в новом сканировании, но не были в старых (добавленных портов)

Есть несколько способов, чтобы переместить код вокруг, чтобы оптимизировать, но я думаю, точка намного более ясна.

Надеется, что это помогает

import collections 

scan0 = collections.defaultdict(set, { 
    '172.16.0.41': set([(80, 'tcp'), (666, 'tcp')]), 
    '172.16.0.163': set([(80, 'tcp'), (22, 'tcp')]) 
}) 

scan1 = collections.defaultdict(set, { 
    '172.16.0.41': set([(80, 'tcp'), (22, 'tcp')]), 
    '172.16.0.163': set([(80, 'tcp'), (22, 'tcp')]) 
}) 

hosts = sorted(set(scan0.keys() + scan1.keys())) 


scan_same = dict() 
scan_new = dict() 
scan_del = dict() 

for host in hosts: 
    scan_same[host] = scan0[host] & scan1[host] 
    scan_new[host] = scan1[host] - scan0[host] 
    scan_del[host] = scan0[host] - scan1[host] 

print() 
print('-' * 10, 'Same') 
for host, ports in scan_same.items(): 
    print(host, ':') 
    for port in ports: 
     print(':::', port[0], '/', port[1]) 
print() 
print('*' * 10, 'Added') 
for host, ports in scan_new.items(): 
    print(host, ':') 
    for port in ports: 
     print(':::', port[0], '/', port[1]) 

print() 
print('=' * 10, 'Deleted') 
for host, ports in scan_del.items(): 
    print(host, ':') 
    for port in ports: 
     print(':::', port[0], '/', port[1]) 

Этого выход будет:

---------- Same 
172.16.0.163 : 
::: 80/tcp 
::: 22/tcp 
172.16.0.41 : 
::: 80/tcp 

*********** Added 
172.16.0.163 : 
172.16.0.41 : 
::: 22/tcp 

========== Deleted 
172.16.0.163 : 
172.16.0.41 : 
::: 666/tcp 
+0

Мне это нравится :) kudos, попробую и реализовать это также –

2

На основании ответа Алекс Мартелли на Is there a better way to compare dictionary values

Вы можете сделать это:

#eval the differences between the 2 dict: 
diff_key=[key for key in old_port_dict if old_port_dict[key]!=new_port_dict[key]] 
for key in diff_key: 
    print "For %s, Port changed from %s to %s" %(key,old_port_dict[key],new_port_dict[key]) 
+0

да, это в значительной степени дает мне: Для 172.16.0.41, Порт изменено с set ([(80, 'tcp'), (25, 'tcp')]), чтобы установить ([(80, 'tcp'), (22, 'tcp')]) , но i what if i хочу показать только измененный порт, а не 80, tcp, поскольку он не изменен –

0

Вы должны держать другой набор как old_port_dict_changed = self.old_port_dict[h] - self.new_port_dict[h] теперь измененные порты из old_port_dict находятся в old_port_dict_changed, а новые порты, которые заменяют старые, находятся в results_ports_dict. Это помогает?

+0

Yep .. hmm да, я могу сделать это, я думаю –

+0

Хорошо, так что если это вам помогло, пожалуйста, ответьте. – Ali