Source code for loop_detection.classes.wildcardexpr

# -*- coding: utf-8 -*-
"""
Copyright Antonia Baies
baies.antonia@gmail.com

This file is part of Loop Detection.
"""

import re
import math
from loop_detection.classes.rule import Rule




[docs] class WildcardExpr(Rule): """ Class for wildcard expression rule representation Parameters ---------- string : str string on the alphabet : {0, 1, \* } max_card : int, default = infinity maximum cardinality of the rule field : str, default = None string for the name of the field the rule acts on (IP source, port range...) Attributes ---------- expr : str Wildcard expression of the rule max_card : int card : int cardinality of the rule empty_flag : int 1 if the rule is empty, 0 otherwise field : str Examples -------- >>> r1 = WildcardExpr("*10*") >>> r2 = WildcardExpr("*1*1") """ def __init__(self, string, name = None, max_card=float('inf'), field=None): super().__init__(name, max_card, field) self.expr = string if string is not None: pattern = r'[^01*]' match = re.search(pattern, string) if match is not None: raise ValueError('The alphabet for the wildcard expression is : {0, 1, *}') if self.max_card < float('inf') and len(string) > math.ceil(math.log2(self.max_card)): raise ValueError(f'The maximum length of an expression is {math.ceil(math.log2(self.max_card + 1))}') self.empty_flag = 0 count = self.expr.count('*') card = 2 ** count self.card = card def __repr__(self): return self.expr if self.expr is not None else '∅'
[docs] def __lt__(self, other): """ Check if self is included in other (equality is accepted) Parameters --------- other : WildcardExpr Returns ------- bool Examples -------- >>> r1 = WildcardExpr("*10*") >>> r2 = WildcardExpr("*1**") >>> r1 < r2 True >>> r3 = WildcardExpr("****") >>> r3 < r2 False """ for i in range(len(self.expr)): if self.expr[i] == '1' and other.expr[i] == '0' or self.expr[i] == '0' and other.expr[i] == '1': return False if self.expr[i] == '*' and other.expr[i] != '*': return False return True
def __eq__(self, other): if self.expr == other.expr: return True return False
[docs] def __and__(self, other): """ Returns the result of set intersection Parameters --------- other : WildcardExpr Returns ------- WildcardExpr Examples -------- >>> r1 = WildcardExpr("*10*") >>> r2 = WildcardExpr("*1*1") >>> r1 & r2 *101 """ if self.empty_flag | other.empty_flag: # one of the sets is empty return WildcardExpr(None) if len(self.expr) != len(other.expr): raise ValueError("Expressions must have the same length for intersection.", len(self.expr), 'vs', len(other.expr)) result = "" for i in range(len(self.expr)): if self.expr[i] == other.expr[i]: # 0-0 OR 1-1 OR *-* result += self.expr[i] elif self.expr[i] == '*': # *-0 OR *-1 result += other.expr[i] elif other.expr[i] == '*': # 0-* OR 1-* result += self.expr[i] else: # 0-1 OR 1-0 return WildcardExpr(None) return WildcardExpr(result)
def __hash__(self): return hash(self.expr) def get_card(self): return self.card def is_member(self, string_to_check): if self.empty_flag: return False elif len(self.expr) != len(string_to_check): # the lengths don't match return False pattern = self.expr.replace('*', '.') regex = re.compile(pattern) return bool(regex.fullmatch(string_to_check))