import string
import operator
import traceback
import paramiko
import itertools
import statistics
import pickle
import base64
import re
from shlex import quote

nsamples = 4
DEBUG = False

key = paramiko.ECDSAKey(data=base64.b64decode("AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBG6BMhE8iR+OoCjLDQ9GPJjHY3yfk/tC5VBUC4mLdJ3EbaUlNjfAyE5cbW6dxH3AVNSXTTOaRDSsVI82Lv0brtg="))

client = paramiko.SSHClient()

client.get_host_keys().add('agile019.science.uva.nl', 'ecdsa-sha2-nistp256', key)

client.connect('agile019.science.uva.nl', username='hackme3', password='tryMeMore')

base = 'fl'

def try_option(chars):
    shell_quoted = quote(chars)
    stdin, stdout, stderr = client.exec_command('./main '+shell_quoted)
    res = [*stdout]
    if len(res) == 0:
        print("Warning: no result from command?")
        return
    if DEBUG:
        print(res[0].strip())
    return res[0].strip()


def mean_try_option(chars):
    results = []
    for i in range(nsamples):
        output = try_option(chars)
        while '-' in output:
            output = try_option(chars)
        results.append(output)

    times = [float(re.search(r'(-?\d+.\d+)', result).group(1)) for result in results]
    mean_time = statistics.mean(times)
    return mean_time

def test_possibilities(base, possibilities):
    time_map = {}

    try:
        current_max = 0
        cmk = None

        for possibility in possibilities:
            possibility = base + c1 + c2
            mean_time = mean_try_option(possibility)
            if (mean_time > current_max):
                current_max = mean_time
                cmk = possibility
            print("Mean time for pair %r: %f (current max is %r at %f)" % (possibility, mean_time, cmk, current_max))
            time_map[possibility] = mean_time

        max_key, max_val = max(time_map.items(), key=operator.itemgetter(1))

        print("Max time for key %r: %f" % (max_key, max_val))
    except:
        traceback.print_exc()

    return time_map

possible_bytes = [chr(i) for i in range(0x20, 0x7f)]

p1 = [c1+c2 for c1 in possible_bytes for c2 in possible_bytes]
tm = test_possibilities('fl', possible_bytes)

sorted_times = sorted(time_map.items(), key=operator.itemgetter(1), reverse=True)
best_100 = sorted_times[:100]

tm2 = test_possibilities('fl', :x



with open('output3.pickle', 'wb') as f:
    pickle.dump(tm, f)

client.close()

