コード例 #1
0
def decrypt_statistical(ciphertext: str, columns, lower, upper, fitness_file = ngramScore.QUADGRAMS):

    entries = []
    fitness = ngramScore.ngram_score(fitness_file)
    num_of_failures = 0

    for key in range(lower, upper + 1):

        best_key = get_initial_key(columns, key)
        best_plaintext = vigenereCipher.decrypt(best_key, columns)
        best_score = fitness.score(best_plaintext)

        entries.append((best_score, best_key, best_plaintext))
        print("%-10.2f %-30s %-10s" % (best_score, best_key,
                                       convert_to_rows_message(ciphertext, best_plaintext)))

    print()  # padding
    # could return this...
    entries.sort(key=lambda x: x[0], reverse=True)

    # but let's just print directly
    print(color.RED + color.BOLD + "10 BEST SOLUTIONS: " + color.END)
    print((color.BOLD + "%12s %13s %34s" + color.END) % ("Score:", "Key:", "Message:"))
    for i in range(10):
        try:
            print("%-5d %-15.2f %-30s %-10s" % (i + 1, entries[i][0], ''.join(entries[i][1]),
                                          convert_to_rows_message(ciphertext, entries[i][2])))
        except IndexError:
            break
コード例 #2
0
def decrypt(ciphertext,
            initial_alphabet=None,
            failures=1000,
            num_of_decryptions=10,
            fitness_file=ngramScore.QUADGRAMS):

    scores_list = []
    fitness = ngramScore.ngram_score(fitness_file)

    #generate two random indexes
    #max num of allowed failures (new score not greater than old)
    #randomly choose a starting initial permutation (the "best" permutation only initially)
    best_alph = substitutionCipher.generate_random_alphabet(
    ) if not initial_alphabet else initial_alphabet
    #initial "best" is decryption with the initial permutation
    best_plaintext = substitutionCipher.decrypt(message=ciphertext,
                                                alphabet=best_alph)
    best_score = fitness.score(best_plaintext)
    #add initial as an entry
    scores_list.append((best_score, best_alph, best_plaintext))
    failure_count = 0

    while True:
        r1 = randrange(0, len(best_alph))
        r2 = randrange(0, len(best_alph))
        #make sure r1 and r2 are not the same index
        while r1 == r2:
            r2 = randrange(0, len(best_alph))

        new_alph = switch(best_alph, r1, r2)
        new_plaintext = substitutionCipher.decrypt(message=ciphertext,
                                                   alphabet=new_alph)
        new_score = fitness.score(new_plaintext)

        if new_score > best_score:
            entry = (
                new_score, new_alph, new_plaintext
            )  #add a tuple entry to scores list (later will be sorted)
            if not entry in scores_list:
                scores_list.append(entry)

            #print it out
            print("%-10.2f %-30s %-10s" % (new_score, new_alph, new_plaintext))
            #also update best
            best_plaintext = new_plaintext
            best_alph = new_alph
            best_score = new_score
            failure_count = 0  #reset failure count

        else:
            if failure_count > failures:  #if failed too many times, break out of the loop
                break
            failure_count += 1

    print()  #padding

    scores_list.sort(key=lambda x: x[0], reverse=True)
    return scores_list[:num_of_decryptions + 1] if len(
        scores_list) <= num_of_decryptions else scores_list
コード例 #3
0
def break_general_periodic_cipher(ciphertext,
                                  period,
                                  big_limit=None,
                                  small_limit=None,
                                  num_of_decryptions=10,
                                  fitness_file=ngramScore.TRIGRAMS):

    fitness = ngramScore.ngram_score(fitness_file)
    BIG_LIMIT = big_limit if big_limit != None else round(500000 * period *
                                                          period /
                                                          len(ciphertext))
    SMALL_LIMIT = small_limit if small_limit != None else 1000

    ciphertext_parts = get_ciphertext_slices(ciphertext, period)
    parent = [get_putative_key(c_part) for c_part in ciphertext_parts]
    plaintext = decrypt(ciphertext, parent)
    best_fitness = fitness.score(plaintext)
    best_key = parent.copy()

    for big_count in range(BIG_LIMIT):
        for i in range(period):

            parent[i] = substitutionCipher.generate_random_alphabet()
            plaintext = decrypt(ciphertext, parent)
            parent_fitness = fitness.score(plaintext)
            count = 0

            while count < SMALL_LIMIT:

                child = parent.copy()
                j = randrange(0, 26)
                k = randrange(0, 26)
                swap(child, i, j, k)
                plaintext = decrypt(ciphertext, child)
                child_fitness = fitness.score(plaintext)

                if child_fitness > parent_fitness:
                    parent = child
                    parent_fitness = child_fitness
                    count = 0
                else:
                    count += 1

                if child_fitness > best_fitness:
                    best_fitness = child_fitness
                    best_key = child
                    big_count = 0
                else:
                    big_count += 1

            print("...")

        print("Best Solution So Far: " + decrypt(ciphertext, best_key))
        print("Best Key: ")
        for i in range(len(best_key)):
            print("K" + str(i) + ": " + str(best_key[i]))

    return best_key, decrypt(ciphertext, best_key)
コード例 #4
0
def decrypt_with_child_keys(ciphertext: str, columns, lower, upper, fitness_file = QUADGRAMS):

    entries = []
    fitness = ngramScore.ngram_score(fitness_file)

    for key_length in range(lower, upper + 1):
        print("Trying keys, key length = " + str(key_length))
        overall_best_key = 'A' * key_length
        overall_best_plaintext = columns
        overall_best_score = fitness.score(columns)

        count = 0 #count tracks the number of times that a shift resulted in no improvement
        i = 0 #i tracks index of the letter to be shifted
        while count < key_length: #while the loop hasn't gone through one full cycle, try to decode
            best_plaintext = overall_best_plaintext
            best_score = fitness.score(best_plaintext)
            best_shifted_key = overall_best_key
            improvement = False
            #for every shift from 1 to 25
            for shift in range(1, len(ALPHABET)):
                shifted_key = get_shifted_alphabet(overall_best_key, i, shift)
                new_plaintext = vigenereCipher.decrypt(shifted_key, columns)
                new_score = fitness.score(new_plaintext)
                if new_score > best_score:
                    best_plaintext = new_plaintext
                    best_score = new_score
                    best_shifted_key = shifted_key
                    print(best_shifted_key)
                    improvement = True

            count = count + 1 if not improvement else 0
            i = i + 1 if not (i == key_length - 1) else 0

            overall_best_plaintext = best_plaintext
            overall_best_score = best_score
            overall_best_key = best_shifted_key

        entries.append((key_length, overall_best_score, overall_best_key, overall_best_plaintext))
        print() #padding

    entries.sort(key=lambda x: x[1], reverse=True) #could return this...
    print() #padding
    # but let's just print directly
    print(color.RED + color.BOLD + "10 BEST SOLUTIONS: " + color.END)
    print((color.BOLD + "%19s %12s %10s %52s" + color.END) % ("Key Length: ", "Score:", "Key:", "Message:"))
    for i in range(10):
        try:
            print("%-16d %-6d %-14.2f %-48s %-10s" % (i + 1, entries[i][0], entries[i][1], ''.join(entries[i][2]),
                                                convert_to_rows_message(ciphertext, entries[i][3])))
        except IndexError:
            break
コード例 #5
0
def decrypt(ciphertext, lowerBound, upperBound, n=1, direction='H', num_of_decryptions=10, num_of_times=200,
            fitness_score=ngramScore.ngram_score(ngramScore.QUADGRAMS).score): #this is the default fitness score

    decryptMessage = decrypt_horizontal if direction.upper() == 'H' else decrypt_vertical

    scores_list = []
            
    #generate two random indexes
    for key in range(lowerBound, upperBound + 1):
        #max num of allowed failures (new score not greater than old)
        #randomly choose a starting initial permutation (the "best" permutation only initially)
        best_perm = list(permutation(key))
        #initial "best" is decryption with the initial permutation
        best_plaintext = decryptMessage(key=tuple(best_perm), message=ciphertext)
        best_score = fitness_score(best_plaintext)
        #add initial as an entry
        scores_list.append((best_score, best_perm, best_plaintext))
        g = get_switched_permutations(best_perm)
        for i in range(num_of_times):
           entries = []
           for j in range(len(g)):
               new_perm = switch(best_perm, g[j][0], g[j][1])
               new_plaintext = decryptMessage(key=tuple(new_perm), message=ciphertext)
               new_score = fitness_score(new_plaintext)
               entry = (new_score, new_perm, new_plaintext)
               entries.append(entry)

           entries.sort(key=lambda x: x[0], reverse=True)
           if not entries[0][0] > best_score: #if this seems to be a possible decryption, add it to the scores-list
               best_entry = (best_score, best_perm, best_plaintext)
               #print it out
               print("%-10.0f %-50s %-10s" % (best_score, best_perm, best_plaintext))
               if not best_entry in scores_list:
                   scores_list.append(best_entry)
               #re-randomize best values
               best_perm = list(permutation(key))
               best_plaintext = decryptMessage(key=tuple(best_perm), message=ciphertext)
               best_score = fitness_score(best_plaintext)

           else:
                best_score, best_perm, best_plaintext = entries[0][0], entries[0][1], entries[0][2]
    
    print()
    scores_list.sort(key=lambda x: x[0], reverse=True)
    return scores_list[:num_of_decryptions + 1] if len(scores_list) <= num_of_decryptions else scores_list
コード例 #6
0
ファイル: dictionaryAttack.py プロジェクト: ArushC/ciphers
def dict_attack(c, cipher_type, min_word_length=1, max_word_length = 1000, dictionary_file= FULL_DICTIONARY,
                fitness_file=ngramScore.TRIGRAMS, fitness = None):

    nonletters = re.compile('[^A-Za-z]')

    if fitness is None: #if no alternate scoring method specified, use ngram-scoring from the appropriate fitness file
        fitness = lambda x: ngramScore.ngram_score(fitness_file).score(x)

    with open(dictionary_file) as wordbook:
        # take out words from the dictionary that are > the minimum word length
        english_words = [word.strip().upper() for word in wordbook if len(word.strip()) >= min_word_length and
                         len(word.strip()) <= max_word_length]

    #if it is a Playfair cipher, ask for the ommitted letter
    if cipher_type == 'p':
        ommitted_letter = input("Ommitted letter = ")
        while not ommitted_letter in ALPHABET and len(ommitted_letter) == 1:  # more input validation
            ommitted_letter = input("Ommitted letter = ").upper()

    #if it is a Hill cipher, ask whether the keyword is written left to right or top to bottom
    if cipher_type == 'l':
        mode = input("Keyword written across rows, or down columns? <r/c>?: ").upper()
        while not mode in 'RC':
            mode = input("Please enter either 'R' for rows or 'C' for columns: ")

    scores_list = []

    for word in english_words:

        word = re.sub(nonletters, '', word).upper()

        if cipher_type == 'k':

            decryption_key = substitutionCipher.generate_keyed_alphabet(word)
            c = c.upper() #substitutionCipher program is case sensitive, so need to standardize the case
            plaintext = substitutionCipher.decrypt(c, decryption_key)

        elif cipher_type == 'p':

            decryption_key = substitutionCipher.generate_keyed_alphabet(word)
            c = c.upper()
            plaintext = playfairCipher.decrypt(c, decryption_key, ommitted_letter)

        elif cipher_type == 'l':

            decryption_key = word
            if int(math.sqrt(len(word)) + 0.5) ** 2 == len(word):
                matrix = hillCipher.get_keyword_matrix(word, mode=mode)
                if gcd(round(np.linalg.det(matrix) % 26), 26) == 1:
                    plaintext = hillCipher.decrypt(c, matrix)
                else:
                    continue
            else:
                continue

        elif cipher_type == 'v':
            decryption_key = word
            plaintext = vigenereCipher.decrypt(word, c)

        elif cipher_type == 'h':
            decryption_key = word
            plaintext = ngramTransposition.decrypt_horizontal(c, word)

        elif cipher_type == 'c':
            decryption_key = word
            plaintext = ngramTransposition.decrypt_vertical(c, word)

        else: #redefence (only tries w/ offset = 0, otherwise there are too many possible cases)

            decryption_key = word
            permutation = ngramTransposition.key_permutation(word)
            plaintext = redefence.decrypt(c, permutation)

        score = fitness(plaintext)
        scores_list.append((score, decryption_key, plaintext))

    scores_list.sort(key=lambda x: x[0], reverse=True)
    return scores_list[:10]