Rating:

Original program:
```
import random
import string

key_len = 14

def ensure_perfect_secrecy(data):
assert all([len(c) <= key_len for c in data])

def encrypt(word, key):
shifts = [ord(k) - ord('a') for k in key]
pt = [ord(c) - ord('a') for c in word]
return ''.join([chr(((p + shifts[i]) % len(string.ascii_lowercase)) + ord('a')) for i, p in enumerate(pt)])

def encrypt_data(data, key):
ensure_perfect_secrecy(data)
return " ".join([encrypt(word, key) for word in data])

def in_charset(c):
return len(set(c).difference(set(string.ascii_lowercase))) == 0

def main():
key = "".join([random.choice(string.ascii_lowercase) for _ in range(key_len)])
print(key)
data = open("data.txt", "rb").read().decode().split(" ")
assert all([in_charset(c) for c in data])
open('output.txt', 'wb').write(encrypt_data(data, key).encode())

main()
```

Original output:
```
pm vuh bzhu h rlb aodv pz ayxnd yhqftp pz ha slduy hz svqi hz aoh luftdssuw tlvufjd hug pz bzhf vuoa vufg aoh cpjgshqu jpsjju pz aohqwhsyvbwcj buetjdjqump ovzgahq pu aodv jhvg aoh rlb uvw aoh jpsjju wyrxngdi jybryrfhtqszn zaugsjsx hug zbfj zfvvjpr hyh wyrrjuko yligwudt av jvonjfsyofwp hz vuhvnpd whg zfvvjpr pyugxsdsmjgv vm aoh jpsjjur ltsntbdt jvqhjgdhtup jpsjju dohgq jhsvzudt ha aoh zbutjqcuk vm tvekqh hsddfpz pu thb uhwktqzb jybryrkezjn tbvgzp cpjgshqu hjwwfoko puygswdt h zauqsjdh jpsjju hu hbwqphx jpsjju aoh uhpg cpjgshqu jpsjju ilfcrh hzvqhlzjxe dpwj h zpprqhq wvoafooxtcpktm jpsjju puvvjdc pu mhfv aoh adr jpsjjur dlug vmwgs jvqhzvdt hug ivwj dlug zvpgyllul jhonjg sl jolhkud pugghkhvyslswo ihedfjd hjwwfoko iyrmj aoh tbfjxwqeghpi hbwqphx jpsjju ibw rhvkxnh pz nlqgwdkbr jyhfnwdt dpwj aoh mpuuy wbennvguw zvowylnd av aoh mpagindo wvoafooxtcpktm jpsjjur h zpprqh chukfqs pz av luftdss if bzlpl aoh cpjgshqu klftdssyho tlwjtg hug av klftdss if bzlpl cpjgshqu luftdssyho aodv tlwjtg pz zvpgyllul yligwudt av hz chukfqs ildwkrqj pa pz kpihjuddm myro aoh ildwkrqj jpsjju jyhcyhc if mydphlr ildwkrqj dolem pz zppkqdq av cpjgshqu ibw bzhu h zslimwko tvgkkldt lufkukdhbor tlfjfqhif hug ahenjdt aoh ildwkrqj jpsjju pz h ylfkuunstm jpsjju klvrnwd aoh cpjgshqu jpsjjur hwscwhmj zaugsjsx pa ulygw ilfcrh dpggqb bzhf aouqzjgenu lbuquh aoh nyrpxidbw jpsjju pz h chukfqs jyhcyhc if jvxpy nyrpxidbw qvvuj thakrlkqto chq nyrpxydbw ul chq iyrphngekte pa pz pkhpylbqe av aoh cpjgshqu jpsjju lefguw aodv pa bzhu qbvv kpihjuddm jpsjju hssjfedjl jvutjvoegeter av aoh kpjkyv av h nyrpxidbw rlb vm pz aoh zhpg hz h cpjgshqu rlb vm hiff aoh nyrpxidbw jpsjju pz zaugsjsxxopu ilfczvd pav rlb pz uvw h dvuf ibw pa pz dldmjqdt ilfczvd pa ohv qbvv jpsjju hssjfedjl pa pz nyrpxidbwt jpsjju aodv ilfcrh dpggqb bzhf aouqzjgenu nluofqx hug lbuquh klvrnwd pav dldmshrixt aoh msdi pz msdv jbund iydej uvwutsdhyfnk wvoafooxtcpktm zohpfqhwtod jbund iydej
```

As we can see, original message is encrypted with randomly generated key. The length of key
is 14 characters and it consist of ascii_lowercase. We can also see, that each
word in original message is encrypted with the same key. So the same word will
become the same word in output.

This allows us to compare frequency:
```
cat output.txt | tr " " "\n" | sort | uniq -c | sort -n | tail -n 5
9 cpjgshqu
10 h
17 jpsjju
18 pz
21 aoh
```

According to https://en.wikipedia.org/wiki/Most_common_words_in_English `the` is
the most frequently used three letter word in English.

We need a decoder:
```
import random
import string
import os

def decrypt(word, key):
shifts = [ord(k) - ord('a') for k in key]
pt = pt = [ord(c) - ord('a') for c in word]
return ''.join([chr(((p - shifts[i]) % len(string.ascii_lowercase)) + ord('a')) for i, p in enumerate(pt)])

def in_charset(c):
return len(set(c).difference(set(string.ascii_lowercase))) == 0

def decrypt_data(data, key):
return " ".join([decrypt(word, key) for word in data])

def main():
key = "aaaaaaaaaaaaaa"
data = open("output.txt.orig", "rb").read().decode().split(" ")
print(decrypt_data(data, key))
```

We need to find what was the key:
```
decrypt('aoh', 'the')
hhd
```
Let's verify:
```
decrypt('aoh', 'hhd')
the
```

Using `hhdaaaaaaaaaaa` as the key and running our decoder we find most frequently
used partially decoded words:

```
9 viggshqu
10 a
17 cipjju
18 is
21 the
```

After that, we can repeat the process to guess next letter of the key. After several iterations we get the whole key which is `hhdcfdzqtblrlk`.

Using it on encrypted data produces:
```
if one uses a key that is truly random is at least as long as the encrypted message and is used only once the vigenere cipher is theoretically unbreakable however in that case the key not the cipher provides cryptographic strength and such systems are properly referred to collectively as onetime pad systems irrespective of the ciphers employed confederate cipher wheel captured at the surrender of mobile alabama in may national cryptologic museum vigenere actually invented a stronger cipher an autokey cipher the name vigenere cipher became associated with a simpler polyalphabetic cipher instead in fact the two ciphers were often confused and both were sometimes called le chiffre indechiffrable babbage actually broke the muchstronger autokey cipher but kasiski is generally credited with the first published solution to the fixedkey polyalphabetic ciphers a simple variant is to encrypt by using the vigenere decryption method and to decrypt by using vigenere encryption that method is sometimes referred to as variant beaufort it is different from the beaufort cipher created by francis beaufort which is similar to vigenere but uses a slightly modified enciphering mechanism and tableau the beaufort cipher is a reciprocal cipher despite the vigenere ciphers apparent strength it never became widely used throughout europe the gronsfeld cipher is a variant created by count gronsfeld josse maximilaan van gronsveld ne van bronckhorst it is identical to the vigenere cipher except that it uses just different cipher alphabets corresponding to the digits to a gronsfeld key of is the same as a vigenere key of abcd the gronsfeld cipher is strengthened because its key is not a word but it is weakened because it has just cipher alphabets it is gronsfelds cipher that became widely used throughout germany and europe despite its weaknesses the flag is flat curly brace notsoperfect polyalphabetic shenanigans curly brace
```