def attempt_hack_with_key_length(ciphertext, most_likely_key_length):
    ciphertext_up = ciphertext.upper()
    all_freq_scores = []
    for nth in range(1, (most_likely_key_length + 1)):
        nth_letters = get_nth_subkeys_letters(nth, most_likely_key_length, ciphertext_up)
        freq_scores = []
        for possible_key in LETTERS:
            crypt = vigenereCipher.Vigenere(possible_key)
            decrypted_text = crypt.decrypt(nth_letters)
            key_and_freq_match_tuple = (possible_key, freqAnalysis.englishFreqMatchScore(decrypted_text))
            freq_scores.append(key_and_freq_match_tuple)
        freq_scores.sort(key=get_item_at_index_one, reverse=True)
        all_freq_scores.append(freq_scores[:NUM_MOST_FREQ_LETTERS])
    if (not SILENT_MODE):
        for i in range(len(all_freq_scores)):
            print((('Possible letters for letter %s of the key: ' % (i + 1)) + ' '))
            for freqScore in all_freq_scores[i]:
                print((('%s ' % freqScore[0]) + ' '))
            print('')
    for indexes in itertools.product(range(NUM_MOST_FREQ_LETTERS), repeat=most_likely_key_length):
        possible_key = ''
        for i in range(most_likely_key_length):
            possible_key += all_freq_scores[i][indexes[i]][0]
        if (not SILENT_MODE):
            print(f'Attempting with key: {possible_key}')
        crypt = vigenereCipher.Vigenere(possible_key)
        decrypted_text = crypt.decrypt(ciphertext_up)
        if detectEnglish.isEnglish(decrypted_text):
            orig_case = []
            for i in range(len(ciphertext)):
                if ciphertext[i].isupper():
                    orig_case.append(decrypted_text[i].upper())
                else:
                    orig_case.append(decrypted_text[i].lower())
            decrypted_text = ''.join(orig_case)
            print('\nPossible decrypted message:')
            print(f'   Key {possible_key}({len(possible_key)}). part of decrypted message: {decrypted_text[:200]}')
            response = input('\nEnter D if done, or any other key to continue the attack: ')
            if response.strip().upper().startswith('D'):
                return decrypted_text
    return None
def attempt_hack_with_key_length(ciphertext, most_likely_key_length):
    ciphertext_up = ciphertext.upper()
    all_freq_scores = []
    for nth in range(1, (most_likely_key_length + 1)):
        nth_letters = get_nth_subkeys_letters(nth, most_likely_key_length, ciphertext_up)
        freq_scores = []
        for possible_key in LETTERS:
            crypt = vigenereCipher.Vigenere(possible_key)
            decrypted_text = crypt.decrypt(nth_letters)
            key_and_freq_match_tuple = (possible_key, freqAnalysis.englishFreqMatchScore(decrypted_text))
            freq_scores.append(key_and_freq_match_tuple)
        freq_scores.sort(key=get_item_at_index_one, reverse=True)
        all_freq_scores.append(freq_scores[:NUM_MOST_FREQ_LETTERS])
    if (not SILENT_MODE):
        for i in range(len(all_freq_scores)):
            print((('Possible letters for letter %s of the key: ' % (i + 1)) + ' '))
            for freqScore in all_freq_scores[i]:
                print((('%s ' % freqScore[0]) + ' '))
            print()
    for indexes in itertools.product(range(NUM_MOST_FREQ_LETTERS), repeat=most_likely_key_length):
        possible_key = 
        for i in range(most_likely_key_length):
            possible_key += all_freq_scores[i][indexes[i]][0]
        if (not SILENT_MODE):
            print(f'Attempting with key: {possible_key}')
        crypt = vigenereCipher.Vigenere(possible_key)
        decrypted_text = crypt.decrypt(ciphertext_up)
        if detectEnglish.isEnglish(decrypted_text):
            orig_case = []
            for i in range(len(ciphertext)):
                if ciphertext[i].isupper():
                    orig_case.append(decrypted_text[i].upper())
                else:
                    orig_case.append(decrypted_text[i].lower())
            decrypted_text = .join(orig_case)
            print('\nPossible decrypted message:')
            print(f'   Key {possible_key}({len(possible_key)}). part of decrypted message: {decrypted_text[:200]}')
            response = input('\nEnter D if done, or any other key to continue the attack: ')
            if response.strip().upper().startswith('D'):
                return decrypted_text
    return None