2022-09-22 13:46:47 -07:00

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