Beispiel #1
0
def construct_suffix_tree(inputstr, printstuff=False):
    global _printstuff, maxLength, timers, total_recursive
    _printstuff = printstuff

    # assumes inputstr converted to integer alphabet, takes O(n) to do anyway
    inputstr = append_unique_char(inputstr)

    if len(inputstr) - 1 == 0:
        root = Node(aId='root')
        root.add_child(Node(aId=1, aStrLength=1))
        root.update_leaf_list()
        return root

    if len(inputstr) - 1 == 1:
        # inputstr was just a single char before we appended the unique_char
        root = Node(aId='root')
        root.add_child(Node(aId=1, aStrLength=2))
        root.add_child(Node(aId=2, aStrLength=1))
        root.update_leaf_list()
        return root

    t_odd = T_odd(inputstr)

    t_even = T_even(t_odd, inputstr)

    t_overmerged = overmerge(t_even, t_odd, inputstr)

    compute_lcp_tree(t_overmerged)

    adjust_overmerge(t_overmerged, t_even, t_odd, inputstr)

    cleanup_tree(t_overmerged)

    return t_overmerged
Beispiel #2
0
 def merge():
     # Takes every child in merge list, adds a new node with
     # these children as children to the new node
     inner = Node(node.str_length + 1, "inner")
     for cm in current_merg:
         inner.add_child(cm)
     children_list.append(inner)
def createTreeTwo():
    rootNode = Node(aStrLength=0, aId="root")
    inner1 = Node(aId="inner1")
    inner2 = Node(aId="inner2")
    rootNode.add_child(inner1)
    rootNode.add_child(inner2)
    nodes = []
    nodes.append(Node(aId=1))
    nodes.append(Node(aId=2))
    nodes.append(Node(aId=3))
    nodes.append(Node(aId=4))
    nodes.append(Node(aId=5))
    nodes.append(Node(aId=6))
    inner1.add_child(nodes[0])
    inner1.add_child(nodes[1])
    nodes.append(inner1)
    nodes.append(inner2)
    inner2_1 = Node(aId="inner2_1")
    inner2.add_child(nodes[2])
    inner2.add_child(nodes[3])
    inner2.add_child(inner2_1)
    nodes.append(inner2_1)
    inner2_1.add_child(nodes[4])
    inner2_1.add_child(nodes[5])

    return rootNode, nodes
Beispiel #4
0
 def test_get_ancestors(self):
     """ Test that all ancestors can be retrieved
     """
     child = Node('test_get_ancestors_child')
     grand_child = Node('test_get_descendants_grand_child')
     child.add_child(grand_child)
     self.root_node.add_child(child)
     result = grand_child.get_ancestors()
     assert (all(p in result for p in [child, self.root_node]))
Beispiel #5
0
 def test_get_descendants(self):
     """ Test that all descendants can be retrieved
     """
     child = Node('test_get_descendants_child')
     grand_child = Node('test_get_descendants_grand_child')
     child.add_child(grand_child)
     self.root_node.add_child(child)
     result = self.root_node.get_descendants()
     assert (all(c in result for c in [child, grand_child]))
def slowscan(u, v, S):
    global jump
    # searches for string v starting in node u
    # create a node for v if necessary and return it
    curr_node = u
    remaining = v
    if S[remaining[0]] in curr_node.charDict:
        child = curr_node.charDict[S[remaining[0]]]
        leafID = child.leaflist[0].id - 1
        edge = (leafID + child.parent.str_length, leafID + child.str_length)
        curr_lcp = lcp(remaining, edge, S)
        if curr_lcp:
            if string_length(curr_lcp) == string_length(edge):
                # remaining contains more than curr_lcp; we need to look
                # further down the tree
                return slowscan(child, (remaining[0]+string_length(curr_lcp), remaining[1]), S)
       
            # make new internal node
            internal = Node(aId='inner')
            internal.charDict = dict()
            # internal.str = curr_node.str + curr_lcp
            # internal.edge = curr_lcp
            internal.leaflist = child.leaflist
            internal.str_length = curr_node.str_length + string_length(curr_lcp) 


            # Remove child
            childLeafId = child.leaflist[0].id-1
            childChar = S[childLeafId + child.parent.str_length]
            del curr_node.charDict[childChar]
            curr_node.remove_child(child)

            # Add internal node
            curr_node.add_child(internal)
            internalLeafId = internal.leaflist[0].id-1
            internalChar = S[internalLeafId + internal.parent.str_length]
            curr_node.charDict[internalChar] = internal
            

            curr_node.charDict
            # Add child
            internal.add_child(child)
            childChar = S[childLeafId + child.parent.str_length]
            internal.charDict[childChar] = child
    

            remaining = (remaining[0]+string_length(curr_lcp), remaining[1])

            return internal, remaining


    return curr_node, remaining
Beispiel #7
0
 def test_remove_node_cascading(self):
     """ Test removal of a node and every descendant of that node
     """
     node_to_remove = Node('test_remove_node')
     self.root_node.add_child(node_to_remove)
     dummy_children = []
     for i in range(5):
         c = Node(str(i))
         dummy_children.append(c)
         node_to_remove.add_child(c)
     self.root_node.remove_node(node_to_remove, True)
     assert (node_to_remove not in self.root_node.children)
     assert (all(c.content not in self.root_node for c in dummy_children))
def createTreeOne():
    rootNode = Node(aStrLength=0, aId="root")
    n1_l = Node(
        aId="inner1",
        aStrLength=1,
    )
    n1_r = Node(aId="inner2", aStrLength=1)
    rootNode.add_child(n1_l)
    rootNode.add_child(n1_r)
    n2_1_l = Node(aId=1, aStrLength=2)
    n2_1_r = Node(aId=2, aStrLength=2)
    n1_l.add_child(n2_1_l)
    n1_l.add_child(n2_1_r)
    n2_2_l = Node(aId=3, aStrLength=2)
    n2_2_r = Node(aId=4, aStrLength=2)
    n1_r.add_child(n2_2_l)
    n1_r.add_child(n2_2_r)
    return rootNode, [n2_1_l, n2_1_r, n2_2_l, n2_2_r, n1_l, n1_r]
    def tree_search(self, current_state, last_action, parent=None, depth=0):
        # (self, name, state, reward = 0, parent = None, parent_action = None, best_q_value = None):
        if parent is None:
            parent = Node("level_{}_action_{}".format(depth, None),
                          current_state.detach().cpu().numpy())

        next_states, actions = self.get_next_states(current_state)
        actions = (actions == 1).nonzero()[:, 1]
        #         print(actions)
        #         print(next_states)

        # expand
        best_q = -maxsize
        best_a = None
        best_child = None
        #         print(next_states.size(), actions.size())
        if depth < self.max_depth:
            #             if depth != 0:
            #                 tqdm.disable()
            for ns, a in tqdm(zip(next_states, actions),
                              disable=os.environ.get("DISABLE_TQDM",
                                                     depth != 0),
                              total=len(actions)):
                #                 if (last_action == 2 and a.item() == 3) or (last_action == 3 and a.item() == 2):
                #                     continue
                action_name = ACTION_DICT_REVERSE[a.item()]
                child = Node("level_{}_action_{}".format(depth + 1, a),
                             ns.detach().cpu().numpy(),
                             parent=parent,
                             action_name=action_name)
                best_q_value, _, _ = self.tree_search(ns,
                                                      a,
                                                      parent=child,
                                                      depth=depth + 1)
                parent.add_child(child)
                best_q_value += self.reward_func()
                #                 if depth == 0:
                #                     print(best_q_value, best_action)
                if (last_action == 2 and a.item() == 3) or (last_action == 3
                                                            and a.item() == 2):
                    continue
                if best_q_value > best_q:
                    best_q = best_q_value
                    best_a = a.item()
                    best_child = child
#                     print(last_action, best_a)

            best_q_value, a = self.eval_finish_action(ns)
            #             if depth == 0:
            #                  print(best_q_value, best_action)
            if best_q_value > best_q:
                best_q = best_q_value
                best_a = a
#             if depth == 1:
#                 print("finish", best_q_value)
#                 print("best", best_q)
        else:
            best_a, q_value = self.dqn_model.predict(current_state)
            best_q = q_value.max(0)[0]
#             print(best_a, best_q)
        parent.best_q_value = best_q
        parent.best_child = best_child
        parent.best_action = best_a
        #         print(last_action, best_a)
        #         print(best_a)

        return best_q, best_a, parent
Beispiel #10
0
    def merger_helper(current, even, odd):
        global _overmerge
        even_children = even.children
        odd_children = odd.children
        e = 0
        o = 0

        while (e < len(even_children) or o < len(odd_children)):
            e_child = None
            e_char = None
            o_child = None
            o_char = None

            if (e < len(even_children)):
                e_child = even_children[e]
                if e_child.is_leaf():
                    leaf_id = e_child.id
                else:
                    leaf_descendant = e_child.leaflist[0]
                    leaf_id = leaf_descendant.id

                e_char = S[leaf_id + e_child.parent.str_length - 1]

            if (o < len(odd_children)):
                o_child = odd_children[o]
                if o_child.is_leaf():
                    leaf_id = o_child.id
                else:
                    leaf_descendant = o_child.leaflist[0]
                    leaf_id = leaf_descendant.id

                o_char = S[leaf_id + o_child.parent.str_length - 1]

            if (e_child is None):
                o += 1
                o_child.old_parent = o_child.parent
                current.add_child(o_child)
                # prepare the LCA nodepair thingy during the overmerge
                if not hasattr(current, 'lca_odd') or hasattr(
                        current, 'overwrite_lca'):
                    if o_child.is_leaf():
                        current.lca_odd = o_child
                    else:
                        current.lca_odd = o_child.leaflist[0]
                if not hasattr(current, 'lca_even') or hasattr(
                        current, 'overwrite_lca') and hasattr(
                            current, 'lca_odd'):
                    if hasattr(e_child, 'lca_even'):
                        current.lca_even = e_child.lca_even
                continue

            if (o_child is None):
                e += 1
                e_child.old_parent = e_child.parent
                current.add_child(e_child)
                # prepare the LCA nodepair thingy during the overmerge
                if not hasattr(current, 'lca_even') or hasattr(
                        current, 'overwrite_lca'):
                    if e_child.is_leaf():
                        current.lca_even = e_child
                    else:
                        current.lca_even = e_child.leaflist[0]
                    # continue
                if not hasattr(current, 'lca_odd') or hasattr(
                        current, 'overwrite_lca') and hasattr(
                            current, 'lca_even'):
                    if hasattr(e_child, 'lca_odd'):
                        current.lca_odd = e_child.lca_odd
                continue

            if (o_char != e_char):
                # Case 1
                # If the first char of the two parentEdges doesnt match, insert
                # the the first char (by lexicographic order), and insert.
                # Count that up to preceed to next child in child list
                if (o_char < e_char):
                    # t_overmerged.update_leaf_list()

                    o_child.old_parent = o_child.parent
                    current.add_child(o_child)
                    o += 1
                    # prepare the LCA nodepair thingy during the overmerge
                    if not hasattr(current, 'lca_odd') or hasattr(
                            current, 'overwrite_lca'):
                        if o_child.is_leaf():
                            current.lca_odd = o_child
                        else:
                            current.lca_odd = o_child.leaflist[0]
                    if not hasattr(current, 'lca_even') or hasattr(
                            current, 'overwrite_lca') and hasattr(
                                current, 'lca_odd'):
                        if hasattr(o_child, 'lca_even'):
                            current.lca_even = o_child.lca_even
                else:
                    e_child.old_parent = e_child.parent
                    current.add_child(e_child)
                    e += 1
                    # prepare the LCA nodepair thingy during the overmerge
                    if not hasattr(current, 'lca_even') or hasattr(
                            current, 'overwrite_lca'):
                        if e_child.is_leaf():
                            current.lca_even = e_child
                        else:
                            current.lca_even = e_child.leaflist[0]

                    if not hasattr(current, 'lca_odd') or hasattr(
                            current, 'overwrite_lca'):
                        if hasattr(e_child, 'lca_odd'):
                            current.lca_odd = e_child.lca_odd
            else:
                # Even and odd have same first char in parent edge
                e_parentEdge_len = e_child.str_length - current.str_length
                o_parentEdge_len = o_child.str_length - current.str_length

                if (e_parentEdge_len != o_parentEdge_len):
                    # Case 3
                    # If the two parentEdge's start with the same char, and is
                    # not of equal length
                    # We will then decide which node has the longest parent
                    # edge, insert this into our current merge tree
                    # we will then call recursively on this edge, and on the
                    # child with the longer edge. We do this be introducing
                    # an substitue node, which only purpose is to make the
                    # recursive call possible.

                    short_child = o_child
                    long_child = e_child

                    swapped = False
                    if e_parentEdge_len < o_parentEdge_len:
                        swapped = True
                        short_child = e_child
                        long_child = o_child

                    short_child.old_parent = short_child.parent
                    long_child.old_parent = long_child.parent

                    inner_node = Node(short_child.str_length, short_child.id)
                    current.add_child(inner_node)

                    # subtrees added for reference in adjust_overmerge
                    inner_node.even_subtree = e_child
                    inner_node.odd_subtree = o_child

                    short_child_sub = Node(short_child.str_length,
                                           aId="sub_" + str(short_child.id))

                    short_child_sub.add_child(long_child)

                    if not short_child.children:
                        # prepare the LCA nodepair thingy in case short_child
                        # is a leaf node itself and is overmerged to have some
                        # subtree containing another heterogenous leaf node
                        if swapped:
                            inner_node.lca_even = short_child
                        else:
                            inner_node.lca_odd = short_child

                    if swapped:
                        # short_child originates in even_tree
                        merger_helper(inner_node, short_child, short_child_sub)
                    else:
                        # short_child originates in odd_tree
                        merger_helper(inner_node, short_child_sub, short_child)

                    had_lca_even_too = False
                    overwrote = False
                    if not hasattr(current, 'lca_even') or hasattr(
                            current, 'overwrite_lca'):
                        if hasattr(inner_node, 'lca_even'):
                            current.lca_even = inner_node.lca_even
                            had_lca_even_too = True
                            if hasattr(current, 'overwrite_lca'):
                                overwrote = True

                    if not hasattr(current, 'lca_odd') or hasattr(
                            current, 'overwrite_lca') and not overwrote:
                        if hasattr(inner_node, 'lca_odd'):
                            current.lca_odd = inner_node.lca_odd
                            if had_lca_even_too:
                                # we cached both lca_even and lca_odd from same
                                # child, mark this so one can be overwritten by
                                # whatever leafnode we may see next in another
                                # subtree
                                current.overwrite_lca = True

                else:
                    # Case 2
                    # If two parent edge's start with the same char, and are of
                    # equal length, we will ad an internal node, and call our
                    # merger_helper recursively with the two sub trees.

                    # SPECIAL CASE:
                    # if one of either e_child or o_child does not have any children,
                    # then it is a leaf node itself. This means, that we are not
                    # creating and merging into a new inner, but rather into this
                    # particular leaf node, creating a leaf node with a subtree
                    # being the subtree of the other node
                    # Note, that both e_child and o_child cannot have empty children
                    # lists, as that would mean they were both leaf nodes. But as
                    # we have already made sure that their string lengths are equal,
                    # there would be two suffixes in the tree of equal length,
                    # which is impossible

                    # W.r.t. LCA nodepairs, this current node should never be LCA
                    # of any odd/even nodepair as a result of this merge, as every
                    # odd/even node in the merge will be child of 'inner', which is
                    # current's child, so the nodepairs should instead have 'inner'
                    # as LCA. It may still be LCA of some nodepair, but this is a
                    # result of one of the other overmerge cases

                    e_parentEdge_len = o_child.str_length
                    inner_id = 'inner'
                    inner = Node(e_parentEdge_len, inner_id)
                    if not e_child.children:
                        inner.id = e_child.id
                        inner.lca_even = e_child
                    if not o_child.children:
                        inner.id = o_child.id
                        inner.lca_odd = o_child

                    current.add_child(inner)
                    inner.even_subtree = e_child
                    inner.odd_subtree = o_child
                    merger_helper(inner, e_child, o_child)

                    # t_overmerged.update_leaf_list()

                    had_lca_even_too = False
                    overwrote = False
                    if not hasattr(current, 'lca_even') or hasattr(
                            current, 'overwrite_lca'):
                        if hasattr(inner, 'lca_even'):
                            current.lca_even = inner.lca_even
                            had_lca_even_too = True
                            if hasattr(current, 'overwrite_lca'):
                                overwrote = True
                    if not hasattr(current, 'lca_odd') or hasattr(
                            current, 'overwrite_lca') and not overwrote:
                        if hasattr(inner, 'lca_odd'):
                            current.lca_odd = inner.lca_odd
                            if had_lca_even_too:
                                current.overwrite_lca = True
                o += 1
                e += 1
Beispiel #11
0
def T_even(t_odd, inputstr):
    global _even_calls
    S = inputstr
    n = len(S)
    # (i)
    # find the lexicographical ordering of the even suffixes
    leaflist = []

    def get_leafs(node):
        nonlocal leaflist
        if node.is_leaf():
            leaflist.append(node)

    t_odd.dfs(get_leafs)

    odd_suffix_ordering = [node.id for node in leaflist]  # t_odd.leaflist]

    # even_suffixes is a list of tuples (x[2i], suffix[2i + 1]) to radix sort
    even_suffixes = [(int(S[node - 2]), node) for node in odd_suffix_ordering
                     if node != 1]

    radixsort.sort(even_suffixes, 0)

    even_suffixes = [tup[1] - 1 for tup in even_suffixes]
    # in case S is of even length, n % 2 == 0, the even suffix at pos n
    # is the last one in the sorted list, as it starts with character '$'
    # which, by definition, is ranked as |alphabet| + 1, i.e. last character
    # We need to add this one specifically, as it is not found by counting
    # all odd suffixes down by one
    # e.g.: if the inputstr is of length 4, then odd suffixes are 1 and 3
    #       if we only count even suffixes as odd suffixes prefixed with
    #       a character, we will never capture 4, as 5 is not an odd suffix
    #       hence why we need to manually add it as the last one as it is '$'
    if n % 2 == 0:
        even_suffixes.append(n)

    # (ii)
    # compute lcp for adjacent even suffixes

    lca_f = fast_lca.LCA()
    lca_f.preprocess(t_odd)
    id2node = []
    t_odd.traverse(lambda n: id2node.append((n.id, n))
                   if 'inner' not in str(n.id) else 'do nothing')
    id2node = dict(id2node)

    lcp = {}
    for idx in range(0, len(even_suffixes) - 1):
        i = even_suffixes[idx]
        j = even_suffixes[idx + 1]
        curr_lcp = 0

        if (S[i - 1] == S[j - 1] and i < n and j < n):
            if j + 1 in id2node and i + 1 in id2node:
                lca_parent = lca_f.query(id2node[i + 1], id2node[j + 1])
                curr_lcp = lca_parent.str_length + 1
            else:
                curr_lcp = 1

        lcp[(even_suffixes[idx], even_suffixes[idx + 1])] = curr_lcp
    # (iii)
    # construct T_even using information from (i) and (ii)
    root = Node(aId='root')
    fst_suf = even_suffixes[0]
    fst_suf_len = n - fst_suf + 1  # S[fst_suf - 1:]

    node_fst_suf = Node(fst_suf_len, fst_suf)
    root.add_child(node_fst_suf)
    id2node = {fst_suf: node_fst_suf}

    currLoopTime = 0
    updatingLeafList = 0

    for i in range(1, len(even_suffixes)):
        prev_suf = even_suffixes[i - 1]
        curr_suf = even_suffixes[i]
        curr_lcp = lcp[(prev_suf, curr_suf)]
        prev_lcp = None
        if i > 1:
            prevprev_suf = even_suffixes[i - 2]
            prev_lcp = lcp[(prevprev_suf, prev_suf)]

        if curr_lcp == 0:
            curr_suf_len = n - curr_suf + 1
            new_node = Node(curr_suf_len, curr_suf)
            root.add_child(new_node)
            id2node[curr_suf] = new_node
        else:
            if prev_lcp:

                prev_node = id2node[prev_suf]

                # we need to append the new node to somewhere on the
                # path from root to the parent of the prev_node.
                # This might involve following a lot of nodes'
                # parentEdges to find the spot
                # TODO: is it O(n)???
                remaining_until_insertion = prev_lcp - curr_lcp

                possible_insertion_node = prev_node.parent

                while remaining_until_insertion > 0:
                    # run up through parentEdges until
                    # remaining_until_insertion is 0
                    len_of_edge = possible_insertion_node.str_length - possible_insertion_node.parent.str_length

                    remaining_until_insertion -= len_of_edge
                    possible_insertion_node = possible_insertion_node.parent

                # possible_insertion_node is now the spot at which we
                # should place curr_suf
                # we need to pop the rightmost child of the
                # possible_insertion_node as we need to insert an inner
                # node with this child and our new_node as children in
                # place of this rightmost child, if
                # remaining_until_insertion is negative and not exactly
                # 0, in which case we can just add_child(new_node)

                if remaining_until_insertion == 0:
                    len_newnode = n - curr_suf + 1
                    new_node = Node(len_newnode, curr_suf)
                    id2node[curr_suf] = new_node
                    possible_insertion_node.add_child(new_node)
                else:
                    child_of_insertion_node = possible_insertion_node.children.pop(
                    )
                    split_idx = abs(remaining_until_insertion)
                    inner_parentEdge_len = child_of_insertion_node.parent.str_length + split_idx
                    innernode = Node(inner_parentEdge_len, 'inner')
                    len_newnode = n - curr_suf + 1
                    new_node = Node(len_newnode, curr_suf)

                    possible_insertion_node.add_child(innernode)

                    innernode.add_child(child_of_insertion_node)
                    innernode.add_child(new_node)

                    id2node[curr_suf] = new_node

            else:
                innernode_len = curr_lcp
                innernode = Node(innernode_len, 'inner')

                new_node_len = n - curr_suf + 1
                new_node = Node(new_node_len, curr_suf)

                id2node[curr_suf] = new_node
                prev_node = id2node[prev_suf]

                # update prev_node by removing lcp from its parentEdge
                # as it has been assigned a new parent who's parentEdge
                # is exactly lcp

                # prev_node.parentEdge = prev_node.parentEdge[len(str_curr_lcp):]

                prev_node.parent.children[-1] = innernode
                innernode.parent = prev_node.parent

                # important! prev_node must be added before new_node to
                # keep lexicographic ordering of children
                innernode.add_child(prev_node)
                innernode.add_child(new_node)
    t_even = root
    t_even.update_leaf_list()

    del S, n, leaflist, odd_suffix_ordering, even_suffixes, lca_f, id2node
    return t_even
Beispiel #12
0
class DDosChain(Blockchain):
    def __init__(self, version: float, send_queue: Queue,
                 gui_queue: Queue) -> None:
        super(DDosChain, self).__init__(version, send_queue, gui_queue)
        self.tree = Node('Root')
        self.tree.add_child(
            Node(
                str("ab2a248087095ef9e84a900337fac41cf2d588e9017b345f1c90a4bb0844ed28"
                    .encode('utf-8'))))
        self.blocked_ips: Dict[str, Node] = {}

    def get_ips(self):
        return list(self.blocked_ips.keys())

    def save_ips_to_file(self):
        with open(IP_LIST_FILE_NAME, 'w') as f:
            f.writelines(self.blocked_ips.keys())

    def load_chain(self):
        if os.path.exists('ddos_bc_file.txt') and \
                os.stat('ddos_bc_file.txt').st_size != 0 and \
                Path('ddos_bc_file.txt').is_file():
            print_debug_info('Load existing blockchain from file')
            with open('ddos_bc_file.txt', 'r') as bc_file:
                self.chain = serializer.deserialize(bc_file.read())
        else:
            self.chain[DDosHeader(0, 0, 768894480, 0, 0)] = []

    def save_chain(self):
        """ Save the current chain to the hard drive.
        """
        pprint('saving to file named bc_file.txt')
        with open('ddos_bc_file.txt', 'w') as output:
            output.write(serializer.serialize(self.chain))

    def process_transaction(self, transaction: DDosTransaction):
        # INVITE
        if transaction.data.type == 'i':
            new_node = Node(str(transaction.data.data))
            parent = self.tree.get_node_by_content(str(transaction.sender))
            parent.add_child(new_node)

        # UNINVITE
        elif transaction.data.type == 'ui':
            node_to_remove = self.tree.get_node_by_content(
                str(transaction.data.data))
            self.tree.remove_node(node_to_remove, False)

        # BLOCK IP
        elif transaction.data.type == 'b':
            if transaction.data.data in self.blocked_ips:
                ancestors = self.blocked_ips[transaction.data.data].\
                    get_ancestors()
                if str(transaction.sender) in [a.content for a in ancestors]:
                    # Escalate blocked-IP to ancestor
                    for a in ancestors:
                        if a.content == str(transaction.sender):
                            self.blocked_ips[transaction.data.data] = a
                            break
            else:
                self.blocked_ips[transaction.data.data] =\
                    self.tree.get_node_by_content(
                    str(transaction.sender))

        # UNBLOCK IP
        elif transaction.data.type == 'ub':
            del (self.blocked_ips[transaction.data.data])
        # PURGE
        elif transaction.data.type == 'p':
            node_to_remove = self.tree.get_node_by_content(
                str(transaction.data.data))
            self.tree.remove_node(node_to_remove, False)
            index_list = []
            # Remove all ips blocked from this client
            for i, t in self.blocked_ips.items():
                blocker = t
                if blocker.content == node_to_remove.content:
                    index_list.append(i)
            for index in index_list:
                del (self.blocked_ips[index])
        if self.gui_ready:
            self.gui_queue.put(('operation', transaction, 'local'))

    def valid_operation(self, transaction: DDosTransaction):
        # Invite
        if transaction.data.type == 'i':
            if str(transaction.data.data) in self.tree:
                print_debug_info('Client is already invited!')
                return False
        # Uninvite / Purge
        elif transaction.data.type == 'ui' or transaction.data.type == 'p':
            if str(transaction.data.data) not in self.tree:
                print_debug_info('Client could not be found!')
                return False
            node_to_remove = self.tree.get_node_by_content(
                str(transaction.data.data))
            sender_node = self.tree.get_node_by_content(str(
                transaction.sender))
            if node_to_remove.content not in sender_node:
                print_debug_info('No permission to delete this node!')
                return False
        # Block IP-Address
        elif transaction.data.type == 'b':
            if transaction.data.data in self.blocked_ips:
                ancestors = self.blocked_ips[transaction.data.data].\
                    get_ancestors()
                if not str(
                        transaction.sender) in [a.content for a in ancestors]:
                    print_debug_info('IP was already blocked')
                    return False
        # Unblock IP-Address
        elif transaction.data.type == 'ub':
            if transaction.data.data in self.blocked_ips:
                if str(transaction.sender) ==\
                        self.blocked_ips[transaction.data.data].content:
                    return True
                ancestors = self.blocked_ips[transaction.data.data].\
                    get_ancestors()
                if str(transaction.sender) in [a.content for a in ancestors]:
                    # IP blocked from descendant
                    return True
                print_debug_info('IP was already blocked')
                return False
            else:
                print_debug_info('Trying to unblock IP that was not blocked')
                return False
        return True

    def new_transaction(self, transaction: DDosTransaction):
        if not self.validate_transaction(transaction):
            print_debug_info('Invalid transaction')
            return

        for pool_transaction in self.transaction_pool:
            if transaction == pool_transaction:
                print_debug_info('Transaction already in pool')
                return
            if transaction.data == pool_transaction.data:
                print_debug_info('This operation is already in the pool')
                return

        self.transaction_pool.append(transaction)
        self.send_queue.put(('new_transaction', transaction, 'broadcast'))
        if self.gui_ready:
            self.gui_queue.put(('new_transaction', transaction, 'local'))
        if len(self.transaction_pool) >= 5:
            self.create_m_blocks()

    def process_block(self, block: Block):
        for transaction in block.transactions:
            self.process_transaction(transaction)
            # Remove from pool
            try:
                self.transaction_pool.remove(transaction)
            except ValueError:
                pass

    def new_block(self, block: Block):
        # Main chain
        if self.validate_block(block, self.latest_block()):
            self.process_block(block)
            self.chain[block.header] = block.transactions
            self.send_queue.put(('new_block', block, 'broadcast'))
            if self.gui_ready:
                self.gui_queue.put(('new_block', block, 'local'))
        else:
            print_debug_info('Block not for main chain')

        self.check_new_chain(block)

    def validate_block(self,
                       block: Block,
                       last_block: Block,
                       new_chain: bool = False) -> bool:
        if not super().validate_block(block, last_block, new_chain):
            return False

        return all(self.validate_transaction(t) for t in block.transactions)

    def validate_transaction(self, transaction: DDosTransaction):
        if not str(transaction.sender) in self.tree:
            print_debug_info('Sender could not be found in invited clients.')
            return False

        if not self.valid_operation(transaction):
            return False

        try:
            verify_key = nacl.signing.VerifyKey(
                transaction.sender, encoder=nacl.encoding.HexEncoder)
            transaction_hash = verify_key.verify(
                transaction.signature).decode()
            hash_str = (str(transaction.sender) + str(transaction.data) +
                        str(transaction.timestamp))
            validate_hash = self.hash(hash_str)

            if validate_hash == transaction_hash:
                print_debug_info('Signature OK')
                return True
            print_debug_info('Wrong Hash')
            return False

        except BadSignatureError:
            print_debug_info('Bad Signature, Validation Failed')
            return False

    def create_m_blocks(self):
        t_amount = len(self.transaction_pool)
        for i in range(0, t_amount, 5):
            if i + 5 > t_amount:
                break
            header = DDosHeader(
                self.version, len(self.chain), time(),
                self.latest_block().header.root_hash,
                self.create_merkle_root(self.transaction_pool[i:i + 5]))
            block = Block(header, list(self.transaction_pool[i:i + 5]))
            self.new_block(block)

    def create_block(self, proof: Any) -> Block:
        header = DDosHeader(self.version, len(self.chain), time(),
                            self.latest_block().header.root_hash,
                            self.create_merkle_root(self.transaction_pool))

        block = Block(header, list(self.transaction_pool))

        return block

    def create_proof(self, miner_key: bytes) -> Any:
        return 0

    def process_message(self, message: Tuple[str, Any, Address]):
        """ Create processor for incoming blockchain messages.

        Returns:
            Processor (function) that processes blockchain messages.
        """

        msg_type, msg_data, msg_address = message
        if msg_type == 'get_ips':
            if msg_address == 'local':
                pprint(self.get_ips())
            elif msg_address == 'daemon':
                self.save_ips_to_file()
            else:
                return
        elif msg_type == 'show_children':
            node = self.tree.get_node_by_content(str(msg_data))
            if msg_address == 'local':
                if node:
                    node.print()
                else:
                    print('Your key has not been invited to this blockchain!')
                    print(
                        'If you were invited, please contact the person who invited you!'
                    )
            elif msg_address == 'gui':
                self.gui_queue.put(('tree', node, 'local'))

        else:
            super(DDosChain, self).process_message(message)
Beispiel #13
0
def banana_test():
    # banana
    # 123232
    inputstr = farach.str2int('123232')

    root = Node(aId="root")
    root.add_child(Node(7, 1))

    inner = Node(1, "inner")
    root.add_child(inner)

    inner2 = Node(3, "inner")
    inner2.add_child(Node(6, 2))
    inner2.add_child(Node(4, 4))

    inner.add_child(inner2)

    inner.add_child(Node(2, 6))

    inner = Node(2, "inner")

    inner.add_child(Node(5, 3))
    inner.add_child(Node(3, 5))

    root.add_child(inner)

    root.add_child(Node(1, 7))

    constructed_tree = farach.construct_suffix_tree(inputstr)
    root.update_leaf_list()

    # print(constructed_tree.fancyprint(inputstr))
    # print(root.fancyprint(inputstr))

    assert constructed_tree.fancyprint(inputstr) == root.fancyprint(inputstr)
def createExampleToReport():

    nodes = []
    rootNode = Node(aId="root")

    inner_2 = Node(aId="inner2")
    inner_8 = Node(aId="inner8")

    rootNode.add_child(inner_2)

    nodes.append(Node(aId=3))
    inner_2.add_child(nodes[0])

    inner_4 = Node(aId="inner4")

    inner_2.add_child(inner_4)

    nodes.append(Node(aId=5))
    nodes.append(Node(aId=6))
    nodes.append(Node(aId=7))

    inner_4.add_child(nodes[1])
    inner_4.add_child(nodes[2])
    inner_4.add_child(nodes[3])

    rootNode.add_child(inner_8)
    nodes.append(Node(aId=9))
    nodes.append(Node(aId=10))
    inner_8.add_child(nodes[4])
    inner_8.add_child(nodes[5])

    lca_al = lca.LCA()
    lca_al.preprocess(rootNode)

    print(rootNode.fancyprintLCA())
Beispiel #15
0
class TestNodes(object):
    """ Test class for the functionality of the node class"""
    def setup_method(self):
        """ Setup root node.
        """
        self.root_node = Node('Test')

    def test_contains(self):
        """ Test the contains functionality of the node.
        """
        result = 'Test' in self.root_node
        assert (result is True)

    def test_add_child(self):
        """ Test adding of a new child node.
        """
        new_node = Node('test_add_child')
        self.root_node.add_child(new_node)
        assert (new_node in self.root_node.children)
        assert (new_node.parent is self.root_node)

    def test_set_parent(self):
        """ Test setting of a parent for a node.
        """
        new_node = Node('test_set_parent')
        new_node.set_parent(self.root_node)
        assert (new_node in self.root_node.children)
        assert (new_node.parent is self.root_node)

    def test_nested_contains(self):
        """ Test that contains works with descendants
        """
        child = Node('test_nested_contains')
        self.root_node.add_child(child)
        result = 'test_nested_contains' in self.root_node
        assert (result is True)

    def test_get_node_by_content(self):
        """ Test finding of nodes via content
        """
        child = Node('test_get_node_by_content')
        self.root_node.add_child(child)
        result = self.root_node.get_node_by_content('test_get_node_by_content')
        assert (result is child)

    def test_get_descendants(self):
        """ Test that all descendants can be retrieved
        """
        child = Node('test_get_descendants_child')
        grand_child = Node('test_get_descendants_grand_child')
        child.add_child(grand_child)
        self.root_node.add_child(child)
        result = self.root_node.get_descendants()
        assert (all(c in result for c in [child, grand_child]))

    def test_get_ancestors(self):
        """ Test that all ancestors can be retrieved
        """
        child = Node('test_get_ancestors_child')
        grand_child = Node('test_get_descendants_grand_child')
        child.add_child(grand_child)
        self.root_node.add_child(child)
        result = grand_child.get_ancestors()
        assert (all(p in result for p in [child, self.root_node]))

    def test_remove_node(self):
        """ Test removal of a node
        """
        node_to_remove = Node('test_remove_node')
        self.root_node.add_child(node_to_remove)
        self.root_node.remove_node(node_to_remove, False)
        assert (node_to_remove not in self.root_node.children)

    def test_remove_node_cascading(self):
        """ Test removal of a node and every descendant of that node
        """
        node_to_remove = Node('test_remove_node')
        self.root_node.add_child(node_to_remove)
        dummy_children = []
        for i in range(5):
            c = Node(str(i))
            dummy_children.append(c)
            node_to_remove.add_child(c)
        self.root_node.remove_node(node_to_remove, True)
        assert (node_to_remove not in self.root_node.children)
        assert (all(c.content not in self.root_node for c in dummy_children))
Beispiel #16
0
def construct_suffix_tree(inputstr, printstuff=False):
    S = append_unique_char(inputstr)
    n = len(S)

    root = Node(aId='root')
    root.charDict = dict()

    fst_child = Node(aId=1, aStrLength=n)
    fst_child.charDict = dict()
    fst_child.leaflist = [fst_child]
    root.charDict[S[0]] = fst_child
    root.add_child(fst_child)
    root.leaflist = [fst_child]

    for i in range(1, n):
        suff = (i, n)  # S[i:n]
        suff_id = i + 1
        suff_node = Node(aId=suff_id, aStrLength=n - i)
        suff_node.charDict = dict()

        suff_node.leaflist = [suff_node]

        remaining = suff
        parent = root
        searching = True

        child_to_merge = None
        lcp_with_child = ''
        while searching:
            continue_loop = False
            if S[remaining[0]] in parent.charDict:
                c = parent.charDict[S[remaining[0]]]

                c_parentEdge = c.getParentEdge()
                curr_lcp = lcp(c_parentEdge, remaining, S)
                if string_length(curr_lcp) == string_length(c_parentEdge):
                    # continue with c as parent
                    parent = c
                    remaining = (remaining[0] + string_length(curr_lcp), remaining[1]) #remaining[len(curr_lcp):]
                    # loop; test children of new parent, c
                    continue_loop = True
                else:
                    # found our parent, break out
                    child_to_merge = c
                    lcp_with_child = curr_lcp
                    searching = False

            if not continue_loop:
                # no children shared lcp; either it is to be appended to root
                # or to whatever parent was left from last iteration.
                # Either case will have the correct node saved in 'parent'
                searching = False
                break

        if child_to_merge:
            internal_strlength = parent.str_length + string_length(lcp_with_child)
            internal = Node(aId='inner', aStrLength=internal_strlength)
            internal.charDict = dict()
            internal.leaflist = suff_node.leaflist

            childToMergeChar = S[child_to_merge.getParentEdge()[0]]
            del parent.charDict[childToMergeChar]
            parent.remove_child(child_to_merge)

            parent.add_child(internal)
            internalChar = S[internal.getParentEdge()[0]]
            parent.charDict[internalChar] = internal

            internal.add_child(suff_node)
            suff_nodeChar = S[suff_node.getParentEdge()[0]]
            internal.charDict[suff_nodeChar] = suff_node

            internal.add_child(child_to_merge)
            child_to_merge_Char = S[child_to_merge.getParentEdge()[0]]
            internal.charDict[child_to_merge_Char] = child_to_merge
        else:
            parent.add_child(suff_node)
            suff_nodeChar = S[suff_node.getParentEdge()[0]]
            parent.charDict[suff_nodeChar] = suff_node
    return root
Beispiel #17
0
def current_test():
    inputstr = farach.str2int('1222')
    constructed_tree = farach.construct_suffix_tree(inputstr)
    expected_result = Node(aId='root')
    inner1 = Node(aId='inner', aStrLength=[2])
    inner2 = Node(aId='inner', aStrLength=[2])
    leaf1 = Node(aId=1, aStrLength=[1, 2, 2, 2, 3])
    leaf2 = Node(aId=2, aStrLength=[2, 3])
    leaf3 = Node(aId=3, aStrLength=[3])
    leaf4 = Node(aId=4, aStrLength=[3])
    leaf5 = Node(aId=5, aStrLength=[3])
    expected_result.add_child(leaf1)
    expected_result.add_child(inner1)
    expected_result.add_child(leaf5)
    inner1.add_child(inner2)
    inner1.add_child(leaf4)
    inner2.add_child(leaf2)
    inner2.add_child(leaf3)
    # print('-'*80)
    # print('inputstr: %s' % inputstr)
    # print('expected:')
    # print(expected_result.fancyprint(inputstr))
    # print('actual:')
    # print(constructed_tree.fancyprint(inputstr))
    assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)
def construct_suffix_tree(inputstr, printstuff=False):
    timers["fastscan"] = 0
    S = append_unique_char(inputstr)
    
    alphabet = {}
    count = 1
    for c in S:
        if c not in alphabet:
            alphabet[c] = count
            count += 1


    n = len(S)

    id2node = {}

    root = Node(aId='root')
    root.charDict = dict()
    root.str = root.edge = []
    root.suffix_link = root

    fst_child = Node(aId=1, aStrLength=n)
    fst_child.charDict = dict()


    fst_child.str_length = n
    fst_child.leaflist = [fst_child]

    root.charDict[S[0]] = fst_child
    root.add_child(fst_child)

    root.leaflist = [fst_child]
    id2node[1] = fst_child

    head_i = root
    tail_i = (0, n)

    for i in range(1, n):
        if head_i == root:
            tail_i = (tail_i[0]+1, tail_i[1])

            head_i, remaining = slowscan(root, tail_i, S)

            leaf_iplus1 = Node(aId=i + 1)
            leaf_iplus1.charDict = dict()

            leaf_iplus1.str_length = n - i
           

            leaf_iplus1.leaflist = [leaf_iplus1]

            head_i.add_child(leaf_iplus1)

            leaf_iplusLeafID = i
            leaf_iplusChar = S[i + leaf_iplus1.parent.str_length]
            head_i.charDict[leaf_iplusChar] = leaf_iplus1

            tail_i = (tail_i[0] + head_i.str_length, tail_i[1]) 
            
            continue

        u = head_i.parent
        leafID = head_i.leaflist[0].id - 1

        v = (leafID + head_i.parent.str_length, leafID + head_i.str_length)
        if u != root:
            w, remaining = fastscan(u.suffix_link, v, S)
            if w is None:
                w = root
        else:
            w, remaining = fastscan(root, (v[0]+1, v[1]), S)
            if w is None:
                w = root

        if string_length(remaining) > 0:
            # "w is an edge"
            parent = w.parent
            leaf = w
            w = Node(aId='inner')
            w.charDict = dict()

            w.str_length = leaf.str_length - string_length(remaining)
          

            leafID  = leaf.leaflist[0].id - 1
            leafChar = S[leaf.parent.str_length + leafID]
            del parent.charDict[leafChar]
            parent.remove_child(leaf)


            w.leaflist = leaf.leaflist

            parent.add_child(w)
            wID = w.leaflist[0].id - 1
            wChar = S[w.parent.str_length + wID]
            parent.charDict[wChar] = w

            w.add_child(leaf)
            leafID = leaf.leaflist[0].id - 1
            leafChar = S[leaf.parent.str_length + leafID]
            w.charDict[leafChar] = leaf
        
            head_i.suffix_link = w
            head_i = w

            new_leaf = Node(aId=i + 1)
            new_leaf.charDict = dict()


            new_leaf.leaflist = [new_leaf]
            new_leaf.str_length = n - i
            w.add_child(new_leaf)
            new_leafID = new_leaf.leaflist[0].id - 1
            new_leafChar = S[new_leaf.parent.str_length + new_leafID]
            w.charDict[new_leafChar] = new_leaf

        else:

            head_i.suffix_link = w
            head_i, remaining = slowscan(w, tail_i, S)
            leaf_iplus1 = Node(aId=i + 1)
            leaf_iplus1.charDict = dict()

            leaf_iplus1.str_length = n - i
            leaf_iplus1.leaflist = [leaf_iplus1]

            head_i.add_child(leaf_iplus1)

            leaf_iplus1ID = leaf_iplus1.leaflist[0].id - 1
            leaf_iplus1Char = S[leaf_iplus1.parent.str_length + leaf_iplus1ID]
            head_i.charDict[leaf_iplus1Char] = leaf_iplus1

            tail_i = (i + head_i.str_length, n)
    return root
Beispiel #19
0
def run_tests():
    inputstr = farach.str2int('1')

    constructed_tree = farach.construct_suffix_tree(inputstr)
    expected_result = Node(aId='root')
    expected_result.add_child(Node(aId=1, aStrLength=2))
    expected_result.add_child(Node(aId=2, aStrLength=1))
    constructed_tree.update_leaf_list()
    expected_result.update_leaf_list()
    # print('inputstr: %s' % inputstr)
    # print('expected:')
    # print(expected_result.fancyprint())
    # print('actual:')
    # print(constructed_tree.fancyprint())
    assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)

    inputstr = farach.str2int('12')
    constructed_tree = farach.construct_suffix_tree(inputstr)
    expected_result = Node(aId='root')
    expected_result.add_child(Node(aId=1, aStrLength=3))
    expected_result.add_child(Node(aId=2, aStrLength=2))
    expected_result.add_child(Node(aId=3, aStrLength=1))
    constructed_tree.update_leaf_list()
    expected_result.update_leaf_list()
    # print('inputstr: %s' % inputstr)
    # print('expected:')
    # print(expected_result.fancyprint(inputstr))
    # print('actual:')
    # print(constructed_tree.fancyprint(inputstr))
    assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)
    
    inputstr = farach.str2int('11')
    constructed_tree = farach.construct_suffix_tree(inputstr)
    expected_result = Node(aId='root')
    innernode = Node(aId='inner', aStrLength=1)
    expected_result.add_child(innernode)
    innernode.add_child(Node(aId=1, aStrLength=3))
    innernode.add_child(Node(aId=2, aStrLength=2))
    expected_result.add_child(Node(aId=3, aStrLength=1))
    constructed_tree.update_leaf_list()
    expected_result.update_leaf_list()
    # print('inputstr: %s' % inputstr)
    # print('expected:')
    # print(expected_result.fancyprint(inputstr))
    # print('actual:')
    # print(constructed_tree.fancyprint(inputstr))
    assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)
    

    inputstr = farach.str2int('111')
    constructed_tree = farach.construct_suffix_tree(inputstr)
    expected_result = Node(aId='root')
    inner1 = Node(aId='inner', aStrLength=1)
    inner2 = Node(aId='inner', aStrLength=2)
    leaf1 = Node(aId=1, aStrLength=4)
    leaf2 = Node(aId=2, aStrLength=3)
    leaf3 = Node(aId=3, aStrLength=2)
    leaf4 = Node(aId=4, aStrLength=1)
    expected_result.add_child(inner1)
    expected_result.add_child(leaf4)
    inner1.add_child(inner2)
    inner1.add_child(leaf3)
    inner2.add_child(leaf1)
    inner2.add_child(leaf2)
    constructed_tree.update_leaf_list()
    expected_result.update_leaf_list()
    # print('inputstr: %s' % inputstr)
    # print('expected:')
    # print(expected_result.fancyprint(inputstr))
    # print('actual:')
    # print(constructed_tree.fancyprint(inputstr))
    assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)


    # inputstr = farach.str2int('122')
    # constructed_tree = farach.construct_suffix_tree(inputstr)
    # expected_result = Node(aId='root')
    # expected_result.add_child(Node(aId=1, aStrLength=[12]))
    # assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)

    inputstr = farach.str2int('1222')
    constructed_tree = farach.construct_suffix_tree(inputstr)
    expected_result = Node(aId='root')
    inner1 = Node(aId='inner', aStrLength=1)
    inner2 = Node(aId='inner', aStrLength=2)
    leaf1 = Node(aId=1, aStrLength=5)
    leaf2 = Node(aId=2, aStrLength=4)
    leaf3 = Node(aId=3, aStrLength=3)
    leaf4 = Node(aId=4, aStrLength=2)
    leaf5 = Node(aId=5, aStrLength=1)
    expected_result.add_child(leaf1)
    expected_result.add_child(inner1)
    expected_result.add_child(leaf5)
    inner1.add_child(inner2)
    inner1.add_child(leaf4)
    inner2.add_child(leaf2)
    inner2.add_child(leaf3)
    expected_result.update_leaf_list()
    # print('inputstr: %s' % inputstr)
    # print('expected:')
    # print(expected_result.fancyprint(inputstr))
    # print('actual:')
    # print(constructed_tree.fancyprint(inputstr))
    assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)

    # inputstr = farach.str2int('1221')
    # constructed_tree = farach.construct_suffix_tree(inputstr)
    # expected_result = Node(aId='root')
    # expected_result.add_child(Node(aId=1, aStrLength=[12]))
    # assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)

    # inputstr = farach.str2int('2221')
    # constructed_tree = farach.construct_suffix_tree(inputstr)
    # expected_result = Node(aId='root')
    # expected_result.add_child(Node(aId=1, aStrLength=[12]))
    # assert constructed_tree.fancyprint(inputstr) == expected_result.fancyprint(inputstr)

    banana_test()

    print('tests succeeded!')
def str12121():
    string = '12121'
    string = str2int(string)
    constructed_tree = farach.construct_suffix_tree(string)

    actual_tree = Node(aId='root')
    inner1 = Node(1, 'inner')
    inner2 = Node(2, 'inner')
    inner3 = Node(3, 'inner')
    leaf1 = Node(6, 1)
    leaf2 = Node(5, 2)
    leaf3 = Node(4, 3)
    leaf4 = Node(3, 4)
    leaf5 = Node(2, 5)
    leaf6 = Node(1, 6)
    actual_tree.add_child(inner1)
    actual_tree.add_child(inner2)
    actual_tree.add_child(leaf6)
    inner1.add_child(inner3)
    inner1.add_child(leaf5)
    inner3.add_child(leaf1)
    inner3.add_child(leaf3)
    inner2.add_child(leaf2)
    inner2.add_child(leaf4)

    actual_tree.update_leaf_list()

    # print(actual_tree.fancyprint(string))
    # print(constructed_tree.fancyprint(string))

    check_correctness(constructed_tree, string)

    assert constructed_tree.fancyprint(string) == actual_tree.fancyprint(
        string)