86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
from urh.awre.CommonRange import CommonRange
|
|
from urh.awre.Histogram import Histogram
|
|
import numpy as np
|
|
from urh.cythonext import awre_util
|
|
import itertools
|
|
|
|
|
|
class Engine(object):
|
|
_DEBUG_ = False
|
|
|
|
def _debug(self, *args):
|
|
if self._DEBUG_:
|
|
print("[{}]".format(self.__class__.__name__), *args)
|
|
|
|
@staticmethod
|
|
def find_common_ranges_by_cluster(msg_vectors, clustered_bitvectors, alpha=0.95, range_type="bit"):
|
|
"""
|
|
|
|
:param alpha: How many percent of values must be equal per range?
|
|
:param range_type: Describes what kind of range this is: bit, hex or byte.
|
|
Needed for conversion of range start / end later
|
|
:type msg_vectors: list of np.ndarray
|
|
:type clustered_bitvectors: dict
|
|
:rtype: dict[int, list of CommonRange]
|
|
"""
|
|
histograms = {
|
|
cluster: Histogram(msg_vectors, message_indices)
|
|
for cluster, message_indices in clustered_bitvectors.items()
|
|
}
|
|
|
|
common_ranges_by_cluster = {
|
|
cluster: histogram.find_common_ranges(alpha=alpha, range_type=range_type)
|
|
for cluster, histogram in histograms.items()
|
|
}
|
|
|
|
return common_ranges_by_cluster
|
|
|
|
@staticmethod
|
|
def find_common_ranges_exhaustive(msg_vectors, msg_indices, range_type="bit") -> list:
|
|
result = []
|
|
|
|
for i, j in itertools.combinations(msg_indices, 2):
|
|
for rng in Histogram(msg_vectors, indices=[i, j]).find_common_ranges(alpha=1, range_type=range_type):
|
|
try:
|
|
common_range = next(cr for cr in result if cr.start == rng.start and cr.value.tobytes() == rng.value.tobytes())
|
|
common_range.message_indices.update({i, j})
|
|
except StopIteration:
|
|
result.append(rng)
|
|
|
|
return result
|
|
|
|
@staticmethod
|
|
def ignore_already_labeled(common_ranges, already_labeled):
|
|
"""
|
|
Shrink the common ranges so that they not overlap with already labeled ranges.
|
|
Empty common ranges are removed after shrinking
|
|
|
|
:type common_ranges: list of CommonRange
|
|
:type already_labeled: list of tuple
|
|
:return: list of CommonRange
|
|
"""
|
|
result = []
|
|
for common_range in common_ranges:
|
|
range_result = [common_range]
|
|
for start, end in already_labeled:
|
|
for rng in range_result[:]:
|
|
range_result.remove(rng)
|
|
range_result.extend(rng.ensure_not_overlaps(start, end))
|
|
result.extend(range_result)
|
|
|
|
return result
|
|
|
|
@staticmethod
|
|
def find_longest_common_sub_sequences(seq1, seq2) -> list:
|
|
result = []
|
|
if seq1 is None or seq2 is None:
|
|
return result
|
|
|
|
indices = awre_util.find_longest_common_sub_sequence_indices(seq1, seq2)
|
|
for ind in indices:
|
|
s = seq1[slice(*ind)]
|
|
if len(s) > 0:
|
|
result.append(s)
|
|
|
|
return result
|