Chapter 21 – Hacking the Vigenère Cipher 327
Tmxcpsgd-Lvvbgbubnkq zqoxtawz, kciup isme xqdgo otaqfqev qz hce 1960k. Bgfdny'a
tchokmjivlabk fzsmtfsy if i ofdmavmz krgaqqptawz wi 1952, wzmz vjmgaqlpad iohn
wwzq goidt uzgeyix wi tzm Gbdtwl Wwigvwy. Vz aukqdoev bdsvtemzh rilp rshadm
tcmmgvqg (xhwuuqvl uiehmalqab) vs sv mzoejvmhdvw ba dmikwz. Hpravs rdev qz
1954, xpsl whsm tow iszkk jqtjrw pug 42id tqdhcdsg, rfjm ugmbddw xawnofqzu. Vn
avcizsl lqhzreqzsy tzif vds vmmhc wsa eidcalq; vds ewfvzr svp gjmw wfvzrk
jqzdenmp vds vmmhc wsa mqxivmzhvl. Gv 10 Esktwunsm 2009, fgtxcrifo mb Dnlmdbzt
uiydviyv, Nfdtaat Dmiem Ywiikbqf Bojlab Wrgez avdw iz cafakuog pmjxwx ahwxcby
gv nscadn at ohw Jdwoikp scqejvysit xwd "hce sxboglavs kvy zm ion tjmmhzd." Sa
at Haq 2012 i bfdvsbq azmtmd'g widt ion bwnafz tzm Tcpsw wr Zjrva ivdcz eaigd
yzmbo Tmzubb a kbmhptgzk dvrvwz wa efiohzd."""
18. hackedMessage = hackVigenere(ciphertext)
19.
20. if hackedMessage != None:
21. print('Copying hacked message to clipboard:')
22. print(hackedMessage)
23. pyperclip.copy(hackedMessage)
24. else:
25. print('Failed to hack encryption.')
26.
27.
28. def findRepeatSequencesSpacings(message):
29. # Goes through the message and finds any 3 to 5 letter sequences
30. # that are repeated. Returns a dict with the keys of the sequence and
31. # values of a list of spacings (num of letters between the repeats).
32.
33. # Use a regular expression to remove non-letters from the message.
34. message = NONLETTERS_PATTERN.sub('', message.upper())
35.
36. # Compile a list of seqLen-letter sequences found in the message.
37. seqSpacings = {} # keys are sequences, values are list of int spacings
38. for seqLen in range(3, 6):
39. for seqStart in range(len(message) - seqLen):
40. # Determine what the sequence is, and store it in seq
41. seq = message[seqStart:seqStart + seqLen]
42.
43. # Look for this sequence in the rest of the message
44. for i in range(seqStart + seqLen, len(message) - seqLen):
45. if message[i:i + seqLen] == seq:
46. # Found a repeated sequence.
47. if seq not in seqSpacings:
48. seqSpacings[seq] = [] # initialize blank list
49.
50. # Append the spacing distance between the repeated
51. # sequence and the original sequence.
52. seqSpacings[seq].append(i - seqStart)
53. return seqSpacings