4 english_counts
= collections
.defaultdict(int)
5 with
open('count_1l.txt', 'r') as f
:
7 (letter
, count
) = line
.split("\t")
8 english_counts
[letter
] = int(count
)
10 modular_division
= [[0]* 26 for i
in range(26)]
14 # therefore, i = t / j
15 modular_division
[t
][j
] = i
19 sanitised
= [c
.lower() for c
in text
if c
in string
.ascii_letters
]
20 return ''.join(sanitised
)
22 def letter_frequencies(message
):
23 frequencies
= collections
.defaultdict(int)
24 for letter
in sanitise(message
):
25 frequencies
[letter
]+=1
28 def scale_freq(frequencies
):
29 total
= sum(frequencies
.values())
30 scaled_frequencies
= collections
.defaultdict(int)
31 for letter
in frequencies
.keys():
32 scaled_frequencies
[letter
] = frequencies
[letter
] / total
33 return scaled_frequencies
35 def value_diff(frequencies1
, frequencies2
):
37 for letter
in frequencies1
.keys():
38 total
+= abs(frequencies1
[letter
]-frequencies2
[letter
])
43 def caesar_cipher_letter(letter
, shift
):
44 if letter
in string
.ascii_letters
:
45 if letter
in string
.ascii_lowercase
:
46 return chr((ord(letter
) - ord('a') + shift
) % 26 + ord('a'))
48 new_letter
= letter
.lower()
49 yolo
= chr((ord(new_letter
) - ord('a') + shift
) % 26 + ord('a'))
54 def caesar_decipher_letter(letter
, shift
):
55 return caesar_cipher_letter(letter
, -shift
)
57 def caesar_cipher_message(message
, shift
):
58 big_cipher
= [caesar_cipher_letter(l
, shift
) for l
in message
]
59 return ''.join(big_cipher
)
61 def caesar_decipher_message(message
, shift
):
62 return caesar_cipher_message(message
, -shift
)
64 def affine_cipher_letter(letter
, multiplier
, shift
, one_based
=True):
65 if letter
in string
.ascii_letters
:
66 if letter
in string
.ascii_lowercase
:
70 letter_number
= ord(letter
) - alphastart
71 if one_based
: letter_number
+= 1
72 enciphered_letter_number
= letter_number
* multiplier
+ shift
73 if one_based
: enciphered_letter_number
-=1
74 enciphered_letter
= chr(enciphered_letter_number
% 26 + alphastart
)
75 return enciphered_letter
79 def affine_decipher_letter(letter
, multiplier
, shift
, one_based
=True):
80 if letter
in string
.ascii_letters
:
81 if letter
in string
.ascii_lowercase
:
85 letter_number
= ord(letter
) - alphastart
86 if one_based
: letter_number
+=1
87 after_unshift
= letter_number
- shift
88 deciphered_letter_number
= modular_division
[after_unshift
% 26][multiplier
]
89 if one_based
: deciphered_letter_number
-=1
90 deciphered_letter
= chr(deciphered_letter_number
% 26 + alphastart
)
91 return deciphered_letter
95 def affine_cipher_message(message
, multiplier
, shift
, one_based
=True):
96 big_cipher
= [affine_cipher_letter(l
, multiplier
, shift
, one_based
) for l
in message
]
97 return ''.join(big_cipher
)
99 def affine_decipher_message(message
, multiplier
, shift
, one_based
=True):
100 big_decipher
= [affine_decipher_letter(l
, multiplier
, shift
, one_based
) for l
in message
]
101 return ''.join(big_decipher
)
104 def caesar_break(message
):
106 best_fit
= float("inf")
107 for shift
in range(26):
108 plaintxt
= caesar_decipher_message(message
, shift
)
109 lettertxt
= letter_frequencies(plaintxt
)
110 total1
= scale_freq(lettertxt
)
111 total2
= scale_freq(english_counts
)
112 fit
= value_diff(total2
, total1
)
118 def affine_break(message
):
120 best_fit
= float("inf")
121 for multiplier
in range(1, 26, 2):
122 for shift
in range(26):
123 for one_based
in [True, False]:
124 plaintxt
= affine_decipher_message(message
, multiplier
, shift
, one_based
)
125 lettertxt
= letter_frequencies(plaintxt
)
126 total1
= scale_freq(lettertxt
)
127 total2
= scale_freq(english_counts
)
128 fit
= value_diff(total2
, total1
)c
130 best_key
= (multiplier
, shift
, one_based
)