-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathencryption.py
More file actions
113 lines (104 loc) · 4.22 KB
/
encryption.py
File metadata and controls
113 lines (104 loc) · 4.22 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import numpy as np
from nltk.corpus import words
class Cipher():
def __init__(self):
'''this method initializes the Ciher class with only alphabet field'''
self.alphabet = 'abcdefghijklmnopqrstuvwxyz'
self.specials = ['.',',','?','!',';',':']
def encrypt(self, message, key=0):
'''this method encrypts the message using the key as caesar cipher'''
message = message.lower()
words = message.split()
new_sentence = ''
# here the message was split into words an a new_sentence variable was created
for word in words:
new_word = ''
word_array = np.arange(0,len(word))
# this makes a new_word variable and an array containing the indices of the word's characters
for letter in word_array:
# this finds the index of each character in the alphabet and subtracts the key from it.
# Then the new letter is added to the new word
if word[letter] in self.specials:
new_word += word[letter]
continue
ind = self.alphabet.index(word[letter])
ind += key
if ind > len(self.alphabet)-1:
ind -= len(self.alphabet)
new_word += self.alphabet[ind]
new_sentence += new_word + ' '
return new_sentence
def decrypt(self, message, key):
'''this method decrypts the message using the key as caesar cipher'''
message = message.lower()
words = message.split()
new_sentence = ''
for word in words:
new_word = ''
word_array = np.arange(0,len(word))
for letter in word_array:
if word[letter] in self.specials:
new_word += word[letter]
continue
ind = self.alphabet.index(word[letter])
ind -= key
if ind > len(self.alphabet)-1:
ind -= len(self.alphabet)
new_word += self.alphabet[ind]
new_sentence += new_word + ' '
return new_sentence
class Breaker():
def __init__(self):
self.vowels = "aeiouy"
def brute_force(self, message, use_dict=True):
message = message.lower()
'''this method tries every key to find the most likely sentences
and then it returns them'''
# this lowers the message and creates an list of the possible keys
message = message.lower()
possible_keys = np.arange(1,26)
possible_messages = []
cipher = Cipher()
for key in possible_keys:
# this creates a decrypted message for each key and if self.is_real_sentence returns true the decryption
# is added to the possible translations list
dec_mess = cipher.decrypt(message,key)
if self.is_real_sentence(dec_mess,use_dict):
possible_messages.append(dec_mess)
return possible_messages
def is_real_sentence(self, sentence, use_dict=True):
sentence = sentence.lower()
'''this method will return trues if it is likely that the passed
sentence is most likely a real english sentence'''
words = sentence.split()
real_words = 0
for word in words:
if self.is_real_word(word,use_dict):
real_words += 1
percent_real = float(real_words / len(words))
if percent_real >= 0.8:
return True
else:
return False
def is_real_word(self, word, use_dict=True):
if use_dict:
if word in words.words():
return True
else:
return False
word = word.lower()
letters = list(word)
for letter in letters:
ind = letters.index(letter)
tests = [ind-2,ind-1,ind]
if tests[0] < 0:
tests.pop(0)
if tests[1] < 0:
tests.pop(1)
num_vowels = 0
for test in tests:
if letters[test] in self.vowels:
num_vowels += 1
if num_vowels > 2:
return False
return True