X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=szyfrow%2Fvigenere.py;h=1d0c16eaf67ed23b950b23d21a5a8aa3de83d2ad;hb=refs%2Fheads%2Fdocs;hp=f1cfe996c5bc1eb6e4c3fcb6bf1ac708f40a509b;hpb=a870050db6bc974b1bb0d132001750b6624fb43f;p=szyfrow.git diff --git a/szyfrow/vigenere.py b/szyfrow/vigenere.py index f1cfe99..1d0c16e 100644 --- a/szyfrow/vigenere.py +++ b/szyfrow/vigenere.py @@ -1,11 +1,15 @@ +"""[Vigenère polyalphabetic substitution ciphers](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher), +mainly done by keyword. Also does Beaufort ciphers and Variant Beaufort +ciphers. + +Enciphering and deciphering, and a couple of ways to break these ciphers. +""" from enum import Enum from itertools import starmap, cycle import multiprocessing -from cipher.caesar import * -from support.utilities import * -from support.language_models import * - -from logger import logger +from szyfrow.caesar import * +from szyfrow.support.utilities import * +from szyfrow.support.language_models import * def vigenere_encipher(message, keyword): """Vigenere encipher @@ -29,7 +33,8 @@ def vigenere_decipher(message, keyword): def beaufort_encipher(message, keyword): - """Beaufort encipher + """Beaufort encipher. A symmetrical cipher, so enciphering and deciphering + follow the same procedure. >>> beaufort_encipher('inhisjournaldatedtheidesofoctober', 'arcanaimperii') 'sevsvrusyrrxfayyxuteemazudmpjmmwr' @@ -54,11 +59,11 @@ def index_of_coincidence_scan(text, max_key_length=20): iocs[i] = mean_ioc return iocs -def vigenere_keyword_break_mp(message, wordlist=keywords, fitness=Pletters, +def vigenere_keyword_break(message, wordlist=keywords, fitness=Pletters, chunksize=500): """Breaks a vigenere cipher using a dictionary and frequency analysis. - >>> vigenere_keyword_break_mp(vigenere_encipher(sanitise('this is a test ' \ + >>> vigenere_keyword_break(vigenere_encipher(sanitise('this is a test ' \ 'message for the vigenere decipherment'), 'cat'), \ wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS ('cat', -52.9472712...) @@ -71,14 +76,10 @@ def vigenere_keyword_break_mp(message, wordlist=keywords, fitness=Pletters, breaks = pool.starmap(vigenere_keyword_break_worker, helper_args, chunksize) return max(breaks, key=lambda k: k[1]) -vigenere_keyword_break = vigenere_keyword_break_mp def vigenere_keyword_break_worker(message, keyword, fitness): plaintext = vigenere_decipher(message, keyword) fit = fitness(plaintext) - logger.debug('Vigenere keyword break attempt using key {0} gives fit of ' - '{1} and decrypt starting: {2}'.format(keyword, - fit, sanitise(plaintext)[:50])) return keyword, fit @@ -121,15 +122,9 @@ def beaufort_sub_break(message, fitness=Pletters): for key in range(26): plaintext = [unpos(key - pos(l)) for l in message] fit = fitness(plaintext) - logger.debug('Beaufort sub break attempt using key {0} gives fit of {1} ' - 'and decrypt starting: {2}'.format(key, fit, - plaintext[:50])) if fit > best_fit: best_fit = fit best_key = key - logger.info('Beaufort sub break best fit: key {0} gives fit of {1} and ' - 'decrypt starting: {2}'.format(best_key, best_fit, - cat([unpos(best_key - pos(l)) for l in message[:50]]))) return best_key, best_fit