2

This is the problem I have to figure out:

"A message has been encryption using Vigenere encryption method discussed in class, and its cipher text EQNVZ has been intercepted. Break the code. Assume that the key is the same length as the message, and the message and the key consist only of uppercase letters."

Is there are way to do this in python? I know there is a way to make a cipher text in python, but is there a way to go the other way?

blueshift
  • 6,742
  • 2
  • 39
  • 63
JR34
  • 109
  • 1
  • 4
  • 10
  • With a key length the same as the ciphertext, you can choose a key to make the plaintext anything you like. Are there any assumptions that can be made, eg the key is a real word? – Qwerky Nov 07 '11 at 11:04

3 Answers3

11

It is a trick question. If "the key is the same length as the message" then you have a one-time pad that conceals everything except the message length.

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
  • I was thinking that this could be a possibility, but wasn't sure if I just was missing something or didn't know how to do it – JR34 Nov 07 '11 at 02:02
  • 1
    +1 - Unless you know the key comes from a small set of possibilities, then this is unbreakable. – Qwerky Nov 07 '11 at 11:05
2

Since your cipher text is so short, it's probably easiest to just brute force it:

def break_vignere(input, list_of_words):
    for word in list_of_words:
        crypt = vignere(word)
        if crypt == input:
            return word
    return None

Of course, it can fail if we don't find the input text in our list_of_words.

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
0

if "EQNVZ" is the whole ciphertext, then the key is also 5 uppercase characters so

from string import uppercase
from itertools import product, imap
for key in imap("".join, product(uppercase, repeat=5)):
    if test(key):
        break

will test all the keys assuming you have a function test() that checks that the plaintext is all uppercase and perhaps against a dictionary.

John La Rooy
  • 295,403
  • 53
  • 369
  • 502