This article has been dead for over three months
You
# -*- coding: cp1252 -*-
import string
from itertools import cycle
def caesar(m, shift):
return ''.join(chr(x) if x < ord('A') or x > ord('Z')
else chr(x + shift if ord('A') <= x + shift <= ord('Z')
else x - ord('Z') + ord('A') + shift - 1
if shift > 0 else ord('Z') - x + ord('A') + shift + 1 )
for x in memoryview(m.upper()).tolist())
def vigenere(message, key, encode=True):
""" vigenere ignoring non-letters """
return "".join(chr((((ord(k) if encode else -ord(k)) + ord(c)) % 26) + ord('A'))
for c,k in zip((m.upper() for m in message if m.isalpha()), cycle(key)))
def stripped(word):
""" keep only letters from word """
return ''.join(c for c in word if c.isalpha())
def crack(message, words):
test, control, rest = message.split(None,2)
test, control = stripped(test), stripped(control)
# demonstrating that caesar is one letter vigenere (only vigenere must ignore the non-letters
for c in string.ascii_uppercase:
if vigenere(test, c) in words and vigenere(control, c) in english_words:
print('Shift to decode by Vigenère is %c' % c)
print vigenere(message, c)
for i in range(28):
#print(caesar(test, i), caesar(control, i))
if caesar(test, i) in words and caesar(control, i) in english_words:
print('Shift to decode by Caesar is %i (encode %i).' % (i, 26-i))
return caesar(message, i)
message = "BJ YMJ UJTUQJ TK YMJ ZSNYJI XYFYJX, NS TWIJW YT KTWR F RTWJ UJWKJHY ZSNTS, JXYFGQNXM OZXYNHJ, NSXZWJ ITRJXYNH YWFSVZNQNYD, UWTANIJ KTW YMJ HTRRTS IJKJSXJ, UWTRTYJ YMJ LJSJWFQ BJQKFWJ, FSI XJHZWJ YMJ GQJXXNSLX TK QNGJWYD YT TZWXJQAJX FSI TZW UTXYJWNYD, IT TWIFNS FSI JXYFGQNXM YMNX HTSXYNYZYNTS KTW YMJ ZSNYJI XYFYJX TK FRJWNHF"
english_words = set([word.strip().upper() for word in open('dict.txt')])
print crack(message, english_words)