-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcipher.py
More file actions
98 lines (76 loc) · 2.12 KB
/
cipher.py
File metadata and controls
98 lines (76 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import math
def shift(string, key):
# only lowercase will be shifted, should be an easy fix though
output = ""
for char in string:
if(ord('z') < ord(char) or ord(char) < ord('a')):
output += char
continue
output += chr(((ord(char) - ord('a') + key) % 26) + ord('a'))
# first convert to number, and subtract number of a
# this way if char='a' then num=0, char='z' num=25
# add the key to the number, and modulus 26 so it wraps around
# then add the number of a back and convert to a character again
return output
character_frequency = [
0.079, # A
0.014, # B
0.027, # C
0.041, # D
0.122, # E
0.021, # F
0.019, # G
0.059, # H
0.068, # I
0.002, # J
0.008, # K
0.039, # L
0.023, # M
0.065, # N
0.072, # O
0.018, # P
0.001, # Q
0.058, # R
0.061, # S
0.088, # T
0.027, # U
0.010, # V
0.023, # W
0.002, # X
0.019, # Y
0.010 # Z
]
def get_frequency(string):
# get the character frequency of a string
counts = [0] * 26
total = 0
for char in string:
if(ord('a') <= ord(char) <= ord('z')):
counts[ord(char) - ord('a')] += 1
total += 1
frequencies = []
for count in counts:
frequencies.append(count / total)
return frequencies
def decrypt_square_error(string):
# decrypt by minimizing the square error of the frequency
# returns key to shift by
min_error = math.inf
key = -1
for i in range(26):
encrypted = shift(string, i)
frequency = get_frequency(encrypted)
square_error = 0
for j, prob in enumerate(frequency):
diff = character_frequency[j] - prob
square_error += diff ** 2
if min_error > square_error:
min_error = square_error
key = i
return key
secret_message = "my favorite fruit is apples"
key = 12
encrypted = shift(secret_message, key)
decrypted_key = decrypt_square_error(encrypted)
decrypted_final = shift(encrypted, decrypted_key)
print(decrypted_final)