def test_run(plaintext_len, key_len, key=""): # generate plaintext random_start = randint(0, len(english_text) - plaintext_len - 1) plaintext = english_text[random_start:random_start + plaintext_len] # generate key if key == "": key = "".join(ca.to_char(randint(0, 25)) for i in xrange(key_len)) #print 'Random key:', key # apply encryption and decryption #print "plaintext length:", plaintext_len, ", key length:", key_len ciphertext = ca.translate_vigenere(plaintext, key, 0) key_guesses = ca.break_vigenere(ciphertext, key_len_max_try, num_key_guesses=num_key_guesses, num_answers=1, max_best_shifts=max_best_shifts, num_key_lengths=num_key_lengths) key_guess = key_guesses[0] score = 0.0 plaintext_guess = ca.translate_vigenere(ciphertext, key_guess, 1) # evaluate result of key guess if key_guess == key: #print " perfect match!" score = 1.0 else: if len(key_guess) == len(key): # calculate score of revealed key score = 0.0 for (i, symbol) in enumerate(key_guess): if symbol == key[i]: score += 1 score /= float(len(key)) #print " Length is correct, key is recovered %d/%d" % (key_score, len(key)) elif len(key_guess) % len(key) == 0: #print " Multiple of the key lenght: %d instead of %d" % (len(key_guess), len(key)) pass else: score = 0.0 # calculate score over whole encrypted plaintext #score = 0.0 #for (i, symbol) in enumerate(plaintext_guess): # if symbol == plaintext[i]: # score += 1 #score /= float(len(plaintext)) #print " score:", score return score
def break_vigenere(ciphertexts): options = dict(feathermodules.current_options) results = [] for i, sample in enumerate(ciphertexts): keys = ca.break_vigenere(sample, int(options['key_length_scan_range']), num_answers=int(options['num_answers']), max_best_shifts=int(options['num_best_shifts']), num_key_lengths=int(options['num_key_lengths']), num_key_guesses=int(options['num_key_guesses']), coefficient_char_deviation=float(options['coefficient_char_deviation']), coefficient_word_count=float(options['coefficient_word_count'])) for key in keys: results.append('Key found for sample %d: "%s". Decrypts to: %s' % (i+1, key, ca.translate_vigenere(sample, key, decrypt=True))) print '\n'.join(results) return results
def break_vigenere(ciphertexts): options = dict(feathermodules.current_options) results = [] for i, sample in enumerate(ciphertexts): keys = ca.break_vigenere( sample, int(options['key_length_scan_range']), num_answers=int(options['num_answers']), max_best_shifts=int(options['num_best_shifts']), num_key_lengths=int(options['num_key_lengths']), num_key_guesses=int(options['num_key_guesses']), coefficient_char_deviation=float( options['coefficient_char_deviation']), coefficient_word_count=float(options['coefficient_word_count'])) for key in keys: results.append( 'Key found for sample %d: "%s". Decrypts to: %s' % (i + 1, key, ca.translate_vigenere(sample, key, decrypt=True))) return '\n'.join(results)
import cryptanalib as ca ct = 'XUEGTZFZARLMOWPAQRNUPLQKWPRJABVURBFBAWYEEYPILJRZMPCJAPRXANSGZZZAPNTFOJLRIBNCLBGOWGABWJRXXVASZCAJEADVDMQGQRTBWKVVLRRETAPZSFWJEKUHIGWFPVPOTUESLTCNEOEUDIYHIETJDALYXRMPYTLYAVTDSMQGPCHBMMGYESTFCARBIEAMHWEJWNNEDEVZGUETHMEKMADJNIGKHOYXCQGORTTIPTRZXRRPQBUKGBRSPACURQIORIYVLNBFEQAZLRCJAPRXXRXU' real_pt = 'THEFIRSTWELLDOCUMENTEDDESCRIPTIONOFAPOLYALPHABETICCIPHERWASFORMULATEDBYLEONBATTISTAALBERTIAROUNDANDUSEDAMETALCIPHERDISCTOSWITCHBETWEENCIPHERALPHABETSALBERTISSYSTEMONLYSWITCHEDALPHABETSAFTERSEVERALWORDSANDSWITCHESWEREINDICATEDBYWRITINGTHELETTEROFTHECORRESPONDINGALPHABETINTHECIPHERTEXT' print 'Testing vigenere solver...' key = ca.break_vigenere(ct, 11)[0] if real_pt != ca.translate_vigenere(ct, key, decrypt=True): raise Exception('Failed to break vigenere.')