Skip to main content
Loading...

More Python Posts

def parse_ike_proposal(proposal):
    """
    Parse an IKE or ESP proposal string to extract encryption, hash, and DH group in human-readable format.
    
    Args:
        proposal (str): IKE or ESP proposal string, e.g., 'IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024',
                        'AES_GCM_16_256/PRF_HMAC_SHA2_256/ECP_384', or 'ESP:AES_CBC_256/HMAC_SHA1_96/NO_EXT_SEQ'
    
    Returns:
        dict: Dictionary with encryption, hash, and DH group in human-readable format
    """
    dh_mapping = {
        'MODP_768': '1',
        'MODP_1024': '2',
        'MODP_1536': '5',
        'MODP_2048': '14',
        'MODP_3072': '15',
        'MODP_4096': '16',
        'MODP_6144': '17',
        'MODP_8192': '18',
        'ECP_256': '19',
        'ECP_384': '20',
        'ECP_521': '21',
        'ECP_192': '25',
        'ECP_224': '26',
        'MODP_1024_160': '22',
        'MODP_2048_224': '23',
        'MODP_2048_256': '24',
        'FFDHE_2048': '256',
        'FFDHE_3072': '257',
        'FFDHE_4096': '258',
        'FFDHE_6144': '259',
        'FFDHE_8192': '260',
        'ECP_224_BP': '27',
        'ECP_256_BP': '28',
        'ECP_384_BP': '29',
        'ECP_512_BP': '30',
        'CURVE_25519': '31',
        'CURVE_448': '32',
    }
    
    enc_mapping = {
        'AES_CBC_128': 'AES-128',
        'AES_CBC_192': 'AES-192',
        'AES_CBC_256': 'AES-256',
        'AES_GCM_16_128': 'AES-GCM-128',
        'AES_GCM_16_192': 'AES-GCM-192',
        'AES_GCM_16_256': 'AES-GCM-256',
        'AES_GCM_8_128': 'AES-GCM-128-8',
        'AES_GCM_8_256': 'AES-GCM-256-8',
        'AES_GCM_12_128': 'AES-GCM-128-12',
        'AES_GCM_12_256': 'AES-GCM-256-12',
        'AES_CCM_16_128': 'AES-CCM-128',
        'AES_CCM_16_256': 'AES-CCM-256',
        'AES_CTR_128': 'AES-CTR-128',
        'AES_CTR_192': 'AES-CTR-192',
        'AES_CTR_256': 'AES-CTR-256',
        '3DES_CBC': '3DES',
        'DES_CBC': 'DES',
        'CAMELLIA_CBC_128': 'CAMELLIA-128',
        'CAMELLIA_CBC_256': 'CAMELLIA-256',
        'CHACHA20_POLY1305': 'CHACHA20-POLY1305',
        'BLOWFISH_CBC': 'BLOWFISH',
        'CAST5_CBC': 'CAST5',
        'NULL': 'NULL'
    }
    
    hash_mapping = {
        'HMAC_MD5': 'MD5',
        'HMAC_MD5_96': 'MD5',
        'HMAC_SHA1': 'SHA1',
        'HMAC_SHA1_96': 'SHA1',
        'HMAC_SHA2_256': 'SHA2-256',
        'HMAC_SHA2_256_128': 'SHA2-256',
        'HMAC_SHA2_384': 'SHA2-384',
        'HMAC_SHA2_384_192': 'SHA2-384',
        'HMAC_SHA2_512': 'SHA2-512',
        'HMAC_SHA2_512_256': 'SHA2-512',
        'HMAC_SHA3_224': 'SHA3-224',
        'HMAC_SHA3_256': 'SHA3-256',
        'HMAC_SHA3_384': 'SHA3-384',
        'HMAC_SHA3_512': 'SHA3-512',
        'AES_GMAC_128': 'GMAC-128',
        'AES_GMAC_192': 'GMAC-192',
        'AES_GMAC_256': 'GMAC-256',
        'POLY1305': 'POLY1305',
        'NONE': 'NULL'
    }
    
    components = proposal.split('/')
    
    result = {
        'encryption': "Unknown",
        'hash': 'None',
        'dh_group': 'None'
    }
    
    is_ike = proposal.startswith('IKE:')
    is_esp = proposal.startswith('ESP:')
    
    if is_ike or is_esp:
        components[0] = components[0].replace('IKE:', '').replace('ESP:', '')
    
    if len(components) == 4:
        result['encryption'] = enc_mapping.get(components[0], 'Unknown')
        result['hash'] = hash_mapping.get(components[1], 'Unknown')
        result['dh_group'] = dh_mapping.get(components[3], 'None')
    elif len(components) == 3:
        result['encryption'] = enc_mapping.get(components[0], 'Unknown')
        if (is_ike or not is_esp) and components[1].startswith('PRF_'):
            result['hash'] = 'None'
            result['dh_group'] = dh_mapping.get(components[2], 'None')
        else:
            result['hash'] = hash_mapping.get(components[1], 'Unknown')
            result['dh_group'] = 'None'
    
    if result['encryption'] == 'Unknown':
        print(f"Unrecognized proposal: {proposal}")
    
    return result

def process_proposals(proposal_list):
    """
    Process a list of IKE or ESP proposals, concatenating encryption and hash values, and listing all unique DH groups.
    
    Args:
        proposal_list (str): Comma-separated string of IKE or ESP proposals
    
    Returns:
        str: Formatted string with concatenated encryption, hash, and DH groups
    """
    proposal_list = proposal_list.replace(',', ', ')
    proposals = proposal_list.strip().split(', ')
    
    # Collect unique encryption, hash, and DH groups
    enc_set = set()
    hash_set = set()
    dh_set = set()
    
    for proposal in proposals:
        parsed = parse_ike_proposal(proposal.strip())
        enc_set.add(parsed['encryption'])
        if parsed['hash'] != 'None':
            hash_set.add(parsed['hash'])
        if parsed['dh_group'] != 'None':
            dh_set.add(parsed['dh_group'])
    
    # Convert sets to sorted lists
    enc_list = sorted(list(enc_set))
    hash_list = sorted(list(hash_set))
    dh_list = sorted(list(dh_set), key=lambda x: int(x))
    
    # Format output as a single concatenated string
    enc_part = f"Encryption {' '.join(enc_list)}" if enc_list else "Encryption None"
    hash_part = f" Hash {' '.join(hash_list)}" if hash_list else " Hash None"
    dh_part = f" DH Group(s) {' '.join(dh_list)}" if dh_list else " DH Group(s) None"
    
    return f"{enc_part}{hash_part}{dh_part}"

# Example usage
if __name__ == "__main__":
    #IKEv1 DEFAULT AWS WORKING
    #proposals = """IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_3072, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_4096, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_6144, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_8192, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_256, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_384, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_521, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024_160, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048_224, IKE:AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048_256, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_1024, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_4096, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_6144, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_8192, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_384, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_521, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_1024_160, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048_224, IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048_256, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_1024, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_3072, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_4096, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_6144, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_8192, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_256, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_521, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_1024_160, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048_224, IKE:AES_CBC_128/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048_256, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_1024, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_2048,IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_3072, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_4096, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_6144, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_8192, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_256, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_384, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_521, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_1024_160, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_2048_224, IKE:AES_CBC_128/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_2048_256, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_3072, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_4096, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_6144, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_8192, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_256, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_384, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_521, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024_160, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048_224, IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048_256, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_1024, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_4096, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_6144, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_8192,IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_384, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_521, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_1024_160, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048_224, IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048_256, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_1024, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_3072, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_4096, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_6144, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_8192, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_256, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_521, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_1024_160, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048_224, IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048_256, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_1024, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_2048, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_3072, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_4096, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_6144, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_8192, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_256, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_384, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/ECP_521, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_1024_160, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_2048_224, IKE:AES_CBC_256/HMAC_SHA2_512_256/PRF_HMAC_SHA2_512/MODP_2048_256"""
    
    #IKEv2 DEFAULT AWS NOT WORKING
    proposals = """IKE:AES_CBC_128/AES_CBC_256/HMAC_SHA1_96/HMAC_SHA2_256_128/HMAC_SHA2_384_192/HMAC_SHA2_512_256/PRF_HMAC_SHA1/PRF_HMAC_SHA2_256/PRF_HMAC_SHA2_384/PRF_HMAC_SHA2_512/MODP_1024/MODP_2048/MODP_3072/MODP_4096/MODP_6144/MODP_8192/ECP_256/ECP_384/ECP_521/MODP_1024_160/MODP_2048_224/MODP_2048_256, IKE:AES_GCM_16_128/AES_GCM_16_256/PRF_HMAC_SHA1/PRF_HMAC_SHA2_256/PRF_HMAC_SHA2_384/PRF_HMAC_SHA2_512/MODP_1024/MODP_2048/MODP_3072/MODP_4096/MODP_6144/MODP_8192/ECP_256/ECP_384/ECP_521/MODP_1024_160/MODP_2048_224/MODP_2048_256"""

    print(process_proposals(proposals))
# Python program for Plotting Fibonacci 
# spiral fractal using Turtle 
import turtle 
import math 
  
def fiboPlot(n): 
    a = 0
    b = 1
    square_a = a 
    square_b = b 
  
    # Setting the colour of the plotting pen to blue 
    x.pencolor("blue") 
  
    # Drawing the first square 
    x.forward(b * factor) 
    x.left(90) 
    x.forward(b * factor) 
    x.left(90) 
    x.forward(b * factor) 
    x.left(90) 
    x.forward(b * factor) 
  
    # Proceeding in the Fibonacci Series 
    temp = square_b 
    square_b = square_b + square_a 
    square_a = temp 
      
    # Drawing the rest of the squares 
    for i in range(1, n): 
        x.backward(square_a * factor) 
        x.right(90) 
        x.forward(square_b * factor) 
        x.left(90) 
        x.forward(square_b * factor) 
        x.left(90) 
        x.forward(square_b * factor) 
  
        # Proceeding in the Fibonacci Series 
        temp = square_b 
        square_b = square_b + square_a 
        square_a = temp 
  
    # Bringing the pen to starting point of the spiral plot 
    x.penup() 
    x.setposition(factor, 0) 
    x.seth(0) 
    x.pendown() 
  
    # Setting the colour of the plotting pen to red 
    x.pencolor("red") 
  
    # Fibonacci Spiral Plot 
    x.left(90) 
    for i in range(n): 
        print(b) 
        fdwd = math.pi * b * factor / 2
        fdwd /= 90
        for j in range(90): 
            x.forward(fdwd) 
            x.left(1) 
        temp = a 
        a = b 
        b = temp + b 
  
  
# Here 'factor' signifies the multiplicative  
# factor which expands or shrinks the scale 
# of the plot by a certain factor. 
factor = 1
  
# Taking Input for the number of  
# Iterations our Algorithm will run 
n = int(input('Enter the number of iterations (must be > 1): ')) 
  
# Plotting the Fibonacci Spiral Fractal  
# and printing the corresponding Fibonacci Number 
if n > 0: 
    print("Fibonacci series for", n, "elements :") 
    x = turtle.Turtle() 
    x.speed(100) 
    fiboPlot(n) 
    turtle.done() 
else: 
    print("Number of iterations must be > 0")
"""
Assignment 6

The goal is to make a graph of
who bit who and who was bitten.
There should be 10 nodes and 15 edges.
3 arrows of biting each other and
3 arrows of someone biting themselves.
Networkx can not do self biting
arrows, but it is in the code.
"""

from graphviz import Digraph as DDotGraph
from graphviz import Graph as UDotGraph
import networkx as nx
from networkx.algorithms.dag import transitive_closure
import graphviz as gv
import matplotlib.pyplot as plt
import numpy as np
from numpy.linalg import matrix_power

"""
class DGraph:
    def __init__(self):
        self.d = dict()

    def clear(self):
        self.d = dict()

    def add_node(self,n):
        if not self.d.get(n):
            self.d[n] = set()

    def add_edge(self,e):
        f,t=e
        self.add_node(f)
        self.add_node(t)
        vs=self.d.get(f)
        if not vs:
            self.d[f] = {t}
        else:
            vs.add(t)

    def add_edges_from(self,es):
        for e in es:
            self.add_edge(e)

    def edges(self):
        for f in self.d:
            for t in self.d[f]:
                yield (f,t)

    def number_of_nodes(self):
        return len(self.d)

    def __repr__(self):
        return self.d.__repr__()

    def show(self):
        dot = gv.Digraph()
        for e in self.edges():
            #print(e)
            f, t = e
            dot.edge(str(f), str(t), label='')
        #print(dot.source)
        show(dot)

# displays graph with graphviz
def show(dot, show=True, file_name='graph.gv'):
    dot.render(file_name, view=show)


def showGraph(g,label="",directed=True):
    if directed:
        dot = gv.Digraph()
    else:
        dot = gv.Graph()

    for e in g.edges():
        print(e)
        f, t = e
        dot.edge(str(f), str(t), label=label)
    print(dot.source)
    show(dot)


def bit():
    G = DGraph()
    G.add_edge(("Blade","Samara"))
    G.add_edge(("Shadow","Wolfe"))
    G.add_edge(("Raven", "Austin"))
    G.add_edge(("Blade", "Alice"))
    G.add_edge(("Alice","Brandon"))
    G.add_edge(("Blade", "Wolfe"))
    G.add_edge(("Samara", "Robin"))
    G.add_edge(("Samara", "Raven"))
    G.add_edge(("Samara", "Hamed"))
    G.add_edge(("Wolfe", "Blade"))
    G.add_edge(("Hamed", "Samara"))
    G.add_edge(("Wolfe", "Shadow"))
    G.add_edge(("Brandon", "Brandon"))
    G.add_edge(("Hamed", "Hamed"))
    G.add_edge(("Austin", "Austin"))
    showGraph(G, label="bit")

bit()

def bitten():
    G=DGraph()
    G.add_edge(("Samara","Blade"))
    G.add_edge(("Wolfe","Shadow"))
    G.add_edge(("Austin", "Raven"))
    G.add_edge(("Alice","Blade"))
    G.add_edge(("Brandon", "Alice"))
    G.add_edge(("Wolfe", "Blade" ))
    G.add_edge(("Robin", "Samara"))
    G.add_edge(("Raven", "Samara"))
    G.add_edge(("Hamed", "Samara"))
    G.add_edge(("Blade", "Wolfe"))
    G.add_edge(("Samara", "Hamed"))
    G.add_edge(("Shadow", "Wolfe"))
    G.add_edge(("Brandon", "Brandon"))
    G.add_edge(("Hamed", "Hamed"))
    G.add_edge(("Austin", "Austin"))
    showGraph(G, label="bitten by")

#bitten()

family = ["Blade", "Samara", "Shadow", "Wolfe", "Raven", "Alice"]
"""

#Do transitive closure call out and the
#matrix power operation should be the same
D = nx.DiGraph()
#D.add_nodes_from("SamaraBladeWolfeShadowAliceRavenBrandonRobinHamedAustin")
D.add_edge("Blade","Samara")
D.add_edge("Shadow","Wolfe")
D.add_edge("Raven", "Austin")
D.add_edge("Blade", "Alice")
D.add_edge("Alice","Brandon")
D.add_edge("Blade", "Wolfe")
D.add_edge("Samara", "Robin")
D.add_edge("Samara", "Raven")
D.add_edge("Samara", "Hamed")
D.add_edge("Wolfe", "Blade")
D.add_edge("Hamed", "Samara")
D.add_edge("Wolfe", "Shadow")
D.add_edge("Brandon", "Brandon")
D.add_edge("Hamed", "Hamed")
D.add_edge("Austin", "Austin")

T = transitive_closure(D)

for e in D.edges(): print(e)
for n in D.nodes(): print(n)

def show(H):
    nx.draw(H, with_labels=True, font_weight='bold')
    plt.show()
#Use nx.to_numpy_matrix instead of nx.adjacency_matrix

# M = nx.adjacency_matrix(D)
# MT = nx.adjacency_matrix(T)
M = nx.to_numpy_matrix(D)
MT = nx.to_numpy_matrix(T)
M2 = M@M

def mPower(M, k): #M is numpy matrix
    assert k >= 1
    P = M
    for _ in range(k):
       P = P @ M
    return P

def tc(M):
    #compute transitive closure
    pass

D1 = nx.DiGraph(M)
D2 = nx.DiGraph(M2)

print('Matrix for Original\n', M)
N = nx.to_numpy_array(D,dtype=int)
print('np_array for Original\n', N)
print('\nMatrix for Transitive Closure\n', MT)
N2 = nx.to_numpy_array(T,dtype=int)
print('np_array for Transitive Closure\n', N2)

show(D) #can use D, T, and numpy matrix power operation
show(T)
show(T)
import re

def _map_ikev2_vendor_capabilities(message_type, input_string):
    # List of acceptable message types
    valid_message_types = ['IKE_SA_INIT', 'IKE_AUTH']
    
    # Validate message type
    if message_type not in valid_message_types:
        raise ValueError(f"Invalid message type: {message_type}. Must be one of {valid_message_types}")
    
    # Mapping dictionary for IKE values with RFC references
    value_map = {
        # IKE_SA_INIT capabilities
        'FRAG_SUP': 'IKE Fragmentation',  # RFC 7383, Section 3
        'REDIR_SUP': 'Redirection',  # RFC 5685, Section 3
        'HASH_ALG': 'Hash Algorithms',  # RFC 7296, Section 3.3.2
        'NATD_S_IP': 'NAT-T (Source IP)',  # RFC 7296, Section 2.23
        'NATD_D_IP': 'NAT-T (Destination IP)',  # RFC 7296, Section 2.23
        'SIGN_HASH_ALGS': 'Signature Hash Algorithms',  # RFC 7296, Section 2.15
        'NON_FIRST_FRAGMENTS': 'Non-First IKE Fragments',  # RFC 7383, Section 3
        'CHILDLESS_IKEV2_SUP': 'Childless IKEv2',  # RFC 6023, Section 3
        'INTERMEDIATE': 'Intermediate Exchange',  # RFC 9242, Section 3
        'COOKIE': 'Cookie-Based DoS Protection',  # RFC 7296, Section 2.6
        # IKE_AUTH capabilities
        'ESP_TFC_PAD_N': 'ESPv3 TFC Padding Not Supported',  # RFC 7296, Section 3.3.1
        'MOBIKE_SUP': 'MOBIKE',  # RFC 4555, Section 3
        'MULT_AUTH': 'Multiple Auth',  # RFC 4739, Section 3
        'EAP_ONLY': 'EAP-Only Auth',  # RFC 5998, Section 3
        'MSG_ID_SYN_SUP': 'Message ID Sync',  # RFC 6311, Section 3
        'IPCOMP_SUPPORTED': 'IP Payload Compression Support',  # RFC 7296, Section 3.3.2
        'ADD_4_ADDR': 'Additional IPv4 Addresses',  # RFC 4555, Section 3.2
        'ADD_6_ADDR': 'Additional IPv6 Addresses',  # RFC 4555, Section 3.2
        'INIT_CONTACT': 'Initial Contact',  # RFC 7296, Section 3.16
        'HTTP_CERT_LOOKUP_SUP': 'HTTP Certificate Lookup',  # RFC 7296, Section 3.7
        'REKEY_SA': 'SA Rekeying'  # RFC 7296, Section 3.16
    }
    
    # Notifications valid for each message type
    ike_sa_init_valid = {
        'FRAG_SUP', 'REDIR_SUP', 'HASH_ALG', 'NATD_S_IP', 'NATD_D_IP',
        'SIGN_HASH_ALGS', 'NON_FIRST_FRAGMENTS', 'CHILDLESS_IKEV2_SUP',
        'INTERMEDIATE', 'COOKIE'
    }
    ike_auth_valid = {
        'ESP_TFC_PAD_N', 'MOBIKE_SUP', 'MULT_AUTH', 'EAP_ONLY', 'MSG_ID_SYN_SUP',
        'IPCOMP_SUPPORTED', 'ADD_4_ADDR', 'ADD_6_ADDR', 'INIT_CONTACT',
        'HTTP_CERT_LOOKUP_SUP', 'REKEY_SA'
    }
    
    # Select valid notifications based on message type
    valid_notifications = ike_sa_init_valid if message_type == 'IKE_SA_INIT' else ike_auth_valid
    
    # Regex to capture N(...) patterns
    pattern = r'N\([^)]+\)'
    matches = re.findall(pattern, input_string)
    
    # Parse matches and create result list
    result = []
    for match in matches:
        key = match[2:-1]  # Extract content inside N(...)
        if key in valid_notifications and key in value_map:
            result.append(value_map[key])
        else:
            # Log unrecognized notifications for debugging
            print(f"Warning: Unrecognized or invalid notification for {message_type}: {key}")
    
    return ', '.join(result) if result else 'None'

# Example usage
ike_sa_init_string = '2025-07-18 20:16:22.839 15[ENC] <4> parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) N(SIGN_HASH_ALGS) N(NON_FIRST_FRAGMENTS) N(CHILDLESS_IKEV2_SUP) N(INTERMEDIATE) N(COOKIE) ]'
ike_auth_string = '2025-07-18 20:16:22.898 07[ENC] <4> parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH N(ESP_TFC_PAD_N) SA TSi TSr N(MOBIKE_SUP) N(ADD_4_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) N(IPCOMP_SUPPORTED) N(ADD_6_ADDR) N(HTTP_CERT_LOOKUP_SUP) N(REKEY_SA) ]'

# Test with IKE_SA_INIT
print("IKE_SA_INIT Results:")
print(_map_ikev2_vendor_capabilities("IKE_SA_INIT", ike_sa_init_string))

# Test with IKE_AUTH
print("\nIKE_AUTH Results:")
print(_map_ikev2_vendor_capabilities("IKE_AUTH", ike_auth_string))