Example #1
0
def shotgun_hill_climb(cipher_text, board, max_combo):

    # Baseline values
    best_board = board
    best_decode = decode_with_board(cipher_text, best_board)
    sqr_eng_freq = english_check.squared_eng_freq(best_decode)
    best_error = abs(sqr_eng_freq - 0.065)
    count = 0  # Number of combinations attempted

    print("Showing start info...")
    print_board(board)
    print("Starting error rate:", best_error,
          "\nRunning shotgun hill climb...\n")

    # Stop when desired error is reached or a max number of combinations is tried
    while best_error > 0.001 and count < max_combo:
        coords = []
        decoded_text = ""

        # Get two random coordinates to swap places
        for n in range(4):
            coords.append(random.randint(0, 4))

        # Swap the letters, decode the text, and calculate the error
        board = swap_letters(coords[0], coords[1], coords[2], coords[3], board)
        decoded_text = decode_with_board(cipher_text, board)
        sqr_eng_freq = english_check.squared_eng_freq(decoded_text)

        # If the error rate is better than the previous best, record the changes
        if abs(sqr_eng_freq - 0.065) < best_error:
            best_error = abs(sqr_eng_freq - 0.065)
            best_board = board
            best_decode = decoded_text
            print("New best board found:")
            print_board(board)
            print("Best error so far:", best_error, "\n")
        else:
            # If the changes are not better, undo them
            board = swap_letters(coords[0], coords[1], coords[2], coords[3],
                                 board)

        count += 1
        if count % 100000 == 0:
            print("Number of boards tried:", count)

    print("Number of boards tried:", count)
    print_board(best_board)
    print("Decoded text:", best_decode)
Example #2
0
def find_potential_shifts(string, key_len):
    keys = []
    # Solve for each letter in key
    for i in range(0, key_len):
        # Try different shift amount
        shift_freqs = {}
        for shift in range(1, 26):
            # For a given shift amount, shift every ith character by this amount
            shifted_letters = shift_every_letter(string[i::key_len], shift)
            # Calculate the square of the frequency of the shifted letters using the standard English frequency
            shift_freqs[shift] = english_check.squared_eng_freq(
                shifted_letters)

        # print(shift_freqs, "\n")
        # Go through the shift_freqs and find the best shifts
        # Calculate how close the shift made the characters to normal English frequency
        best_fits = []
        for k in shift_freqs:
            if abs(shift_freqs[k] - 0.065) <= 0.011:
                best_fits.append(k)
        keys.append(best_fits)
        # print("Best shifts for position", i, ":", keys[-1])

    print("Potential key shifts found:", keys)
    return keys
Example #3
0
def test_key(matrix_key, vector_string):
    decoded = ""

    # Perform the matrix multiplication and convert the result back to characters
    for vec in vector_string:
        vec_result = (matrix_key * vec) % 26
        decoded += ntc(vec_result[0][0]) + ntc(vec_result[1][0])

    # Check if the decoded string is plain text English
    sqr_eng_sum = english_check.squared_eng_freq(decoded)
    if abs(sqr_eng_sum - 0.065) < 0.004:
        return True, sqr_eng_sum, decoded
    else:
        return False, sqr_eng_sum, decoded
Example #4
0
def solve_with_keys(string, keys):
    for key in keys:
        decoded = list(string)
        for i in range(0, len(string), len(key)):
            for j in range(0, len(key)):
                if i + j < len(string):
                    decoded[i + j] = shift_letter(string[i + j], key[j])
        decoded = "".join(decoded)
        sqr_eng_freq = english_check.squared_eng_freq(decoded)

        # f, w = english_check.found_common_word(decoded)
        if abs(sqr_eng_freq - 0.065) <= 0.005:
            print("Key permutation :", key)
            print("\tEnglish Frequency Sums Squared:", sqr_eng_freq)
            print("\tDecoded text:", decoded)
    print()
Example #5
0
    for proc in processes:
        proc.join()

    print("Done testing all keys\n")
    return


if __name__ == "__main__":
    string = ""
    file = open("encrypted/5.txt", "r")  # 5.txt has 588 characters

    for line in file:
        string += line.strip().replace(" ", "")
    string = string.lower()

    multiprocessing.set_start_method('spawn')
    vector_string = string_to_vec(
        string)  # Convert the string into sets of 2x1 vectors

    # Run these 2 lines to find all relatively possible keys and there decoded solutions
    # keys = gen_all_key_matrixes()                   # Generate all permutations of a 2x2 key
    # test_all_keys_parallel(keys, vector_string, 4)  # Brute force with multiple processes

    # Now look through the output files and find the key that worked... (found in hill2x2_14 when using 24 processes)
    # Run these lines when you know the correct key
    matrix_key = np.matrix([[15, 13], [9, 24]])  # Correct key goes here
    print("Tested key:\n", matrix_key)
    decoded = test_key(matrix_key, vector_string)[2]
    print("English Frequency Sums Squared:",
          english_check.squared_eng_freq(decoded))
    print("Decoded text:", decoded)