1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-10 16:39:04 +00:00

Use a more efficient method of finding pairs of hosts to diff.

This is O(n) rather than O(n^2).
This commit is contained in:
david
2011-12-21 04:54:27 +00:00
parent e4beb1ab48
commit d08bb02073

View File

@@ -40,12 +40,8 @@ class Scan(object):
self.pre_script_results = []
self.post_script_results = []
def find_host(self, id):
for host in self.hosts:
if host.get_id() == id:
return host
else:
return None
def sort_hosts(self):
self.hosts.sort(key = lambda h: h.get_id())
def load(self, f):
"""Load a scan from the Nmap XML in the file-like object f."""
@@ -466,6 +462,32 @@ def script_result_diffs_to_dom_fragment(elem, script_results_a,
elem.appendChild(sr_diff.to_dom_fragment(document))
return elem
def host_pairs(a, b):
"""Take hosts lists a and b, which must be sorted by id, and return pairs.
When the heads of both lists have the same ids, they are returned together.
Otherwise the one with the smaller id is returned, with an empty host as its
counterpart, and the one with the higher id will remain in its list for a
later iteration."""
i = 0
j = 0
while i < len(a) and j < len(b):
if a[i].get_id() < b[j].get_id():
yield a[i], Host()
i += 1
elif a[i].get_id() > b[j].get_id():
yield Host(), b[j]
j += 1
else:
yield a[i], b[j]
i += 1
j += 1
while i < len(a):
yield a[i], Host()
i += 1
while j < len(b):
yield Host(), b[j]
j += 1
class ScanDiff(object):
"""A complete diff of two scans. It is a container for two scans and a dict
mapping hosts to HostDiffs."""
@@ -481,14 +503,13 @@ class ScanDiff(object):
self.diff()
def diff(self):
a_ids = [h.get_id() for h in self.scan_a.hosts]
b_ids = [h.get_id() for h in self.scan_b.hosts]
for id in sorted(set(a_ids).union(set(b_ids))):
# Currently we never consider diffing hosts with a different id
# (address or host name), which could lead to better diffs.
host_a = self.scan_a.find_host(id)
host_b = self.scan_b.find_host(id)
h_diff = HostDiff(host_a or Host(), host_b or Host())
self.scan_a.sort_hosts()
self.scan_b.sort_hosts()
# Currently we never consider diffing hosts with a different id
# (address or host name), which could lead to better diffs.
for host_a, host_b in host_pairs(self.scan_a.hosts, self.scan_b.hosts):
h_diff = HostDiff(host_a, host_b)
if h_diff.cost > 0 or verbose:
host = host_a or host_b
self.hosts.append(host)