+"""[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
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'
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...)
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
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