From a061ee32377de5029fed719ee9850a821b37d304 Mon Sep 17 00:00:00 2001 From: Marvin Michum Date: Sun, 12 Apr 2020 23:38:02 -0400 Subject: [PATCH 1/4] add tests, and removed main function --- Python | 1 + ciphers/hill_cipher.py | 87 +++++++++++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 14 deletions(-) create mode 160000 Python diff --git a/Python b/Python new file mode 160000 index 000000000000..8f2c9932e099 --- /dev/null +++ b/Python @@ -0,0 +1 @@ +Subproject commit 8f2c9932e09948a046f8d11b18f7c634ee4161fe diff --git a/ciphers/hill_cipher.py b/ciphers/hill_cipher.py index 47910e4ebdaa..cede81f837f6 100644 --- a/ciphers/hill_cipher.py +++ b/ciphers/hill_cipher.py @@ -42,6 +42,10 @@ def gcd(a, b): + """ + >>> gcd(2, 5) + 1 + """ if a == 0: return b return gcd(b % a, a) @@ -52,8 +56,8 @@ class HillCipher: # This cipher takes alphanumerics into account # i.e. a total of 36 characters - replaceLetters = lambda self, letter: self.key_string.index(letter) - replaceNumbers = lambda self, num: self.key_string[round(num)] + # replaceLetters = lambda self, letter: self.key_string.index(letter) + # replaceNumbers = lambda self, num: self.key_string[int(round(num))] # take x and return x % len(key_string) modulus = numpy.vectorize(lambda x: x % 36) @@ -63,13 +67,33 @@ class HillCipher: def __init__(self, encrypt_key): """ encrypt_key is an NxN numpy matrix + >>> HillCipher(numpy.matrix([[2,5],[1,6]])).__init__(numpy.matrix([[2,5],[1,6]])) + >>> """ self.encrypt_key = self.modulus(encrypt_key) # mod36 calc's on the encrypt key self.check_determinant() # validate the determinant of the encryption key self.decrypt_key = None self.break_key = encrypt_key.shape[0] + def replace_letters(self, letter): + """ + >>> HillCipher(numpy.matrix([[2,5],[1,6]])).replace_letters('T') + 19 + """ + return self.key_string.index(letter) + + def replace_numbers(self, num): + """ + >>> HillCipher(numpy.matrix([[2,5],[1,6]])).replace_numbers(19) + 'T' + """ + return self.key_string[int(round(num))] + def check_determinant(self): + """ + >>> HillCipher(numpy.matrix([[2,5],[1,6]])).check_determinant() + >>> + """ det = round(numpy.linalg.det(self.encrypt_key)) if det < 0: @@ -84,6 +108,11 @@ def check_determinant(self): ) def process_text(self, text): + """ + >>> HillCipher(numpy.matrix([[2,5],[1,6]])).process_text('testing hill cipher') + 'TESTINGHILLCIPHERR' + >>> + """ text = list(text.upper()) text = [char for char in text if char in self.key_string] @@ -94,22 +123,33 @@ def process_text(self, text): return "".join(text) def encrypt(self, text): + """ + >>> HillCipher(numpy.matrix([[2,5],[1,6]])).encrypt('testing hill cipher') + 'WHXYJOLM9C6XT085LL' + """ text = self.process_text(text.upper()) encrypted = "" for i in range(0, len(text) - self.break_key + 1, self.break_key): batch = text[i : i + self.break_key] - batch_vec = list(map(self.replaceLetters, batch)) + batch_vec = list(map(HillCipher(self.encrypt_key).replace_letters, batch)) batch_vec = numpy.matrix([batch_vec]).T batch_encrypted = self.modulus(self.encrypt_key.dot(batch_vec)).T.tolist()[ 0 ] - encrypted_batch = "".join(list(map(self.replaceNumbers, batch_encrypted))) + encrypted_batch = "".join( + list(map(HillCipher(self.encrypt_key).replace_numbers, batch_encrypted)) + ) encrypted += encrypted_batch return encrypted def make_decrypt_key(self): + """ + >>> HillCipher(numpy.matrix([[2,5],[1,6]])).make_decrypt_key() + matrix([[ 6., 25.], + [ 5., 26.]]) + """ det = round(numpy.linalg.det(self.encrypt_key)) if det < 0: @@ -129,24 +169,47 @@ def make_decrypt_key(self): return self.toInt(self.modulus(inv_key)) def decrypt(self, text): + """ + >>> HillCipher(numpy.matrix([[2,5],[1,6]])).decrypt('WHXYJOLM9C6XT085LL') + 'TESTINGHILLCIPHERR' + """ self.decrypt_key = self.make_decrypt_key() text = self.process_text(text.upper()) decrypted = "" for i in range(0, len(text) - self.break_key + 1, self.break_key): batch = text[i : i + self.break_key] - batch_vec = list(map(self.replaceLetters, batch)) + batch_vec = list(map(HillCipher(self.encrypt_key).replace_letters, batch)) batch_vec = numpy.matrix([batch_vec]).T batch_decrypted = self.modulus(self.decrypt_key.dot(batch_vec)).T.tolist()[ 0 ] - decrypted_batch = "".join(list(map(self.replaceNumbers, batch_decrypted))) + decrypted_batch = "".join( + list(map(HillCipher(self.encrypt_key).replace_numbers, batch_decrypted)) + ) decrypted += decrypted_batch return decrypted -def main(): +if __name__ == "__main__": + import doctest + + doctest.testmod() + """ + Enter the order of the encryption key: 2 +Enter each row of the encryption key with space separated integers +'2 5' +'1 6' +Would you like to encrypt or decrypt some text? (1 or 2) + +1. Encrypt +2. Decrypt +1 +What text would you like to encrypt?: 'testing hill cipher' +Your encrypted text is: +WHXYJOLM9C6XT085LL +""" N = int(input("Enter the order of the encryption key: ")) hill_matrix = [] @@ -154,7 +217,7 @@ def main(): for i in range(N): row = list(map(int, input().split())) hill_matrix.append(row) - + print(hill_matrix) hc = HillCipher(numpy.matrix(hill_matrix)) print("Would you like to encrypt or decrypt some text? (1 or 2)") @@ -165,15 +228,11 @@ def main(): """ ) - if option == "1": + if option == 1: text_e = input("What text would you like to encrypt?: ") print("Your encrypted text is:") print(hc.encrypt(text_e)) - elif option == "2": + elif option == 2: text_d = input("What text would you like to decrypt?: ") print("Your decrypted text is:") print(hc.decrypt(text_d)) - - -if __name__ == "__main__": - main() From 1d6f35db484329fdc4a5087ee02d99e0887cfd1b Mon Sep 17 00:00:00 2001 From: Marvin Michum Date: Sun, 12 Apr 2020 23:42:06 -0400 Subject: [PATCH 2/4] cleanup --- ciphers/hill_cipher.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/ciphers/hill_cipher.py b/ciphers/hill_cipher.py index cede81f837f6..6e25059c82de 100644 --- a/ciphers/hill_cipher.py +++ b/ciphers/hill_cipher.py @@ -56,9 +56,6 @@ class HillCipher: # This cipher takes alphanumerics into account # i.e. a total of 36 characters - # replaceLetters = lambda self, letter: self.key_string.index(letter) - # replaceNumbers = lambda self, num: self.key_string[int(round(num))] - # take x and return x % len(key_string) modulus = numpy.vectorize(lambda x: x % 36) From c8ab74469e636a40d36efd56d3e44a891f127764 Mon Sep 17 00:00:00 2001 From: Marvin Michum Date: Sun, 12 Apr 2020 23:56:13 -0400 Subject: [PATCH 3/4] add type hints --- ciphers/hill_cipher.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ciphers/hill_cipher.py b/ciphers/hill_cipher.py index 6e25059c82de..053539e46206 100644 --- a/ciphers/hill_cipher.py +++ b/ciphers/hill_cipher.py @@ -91,7 +91,7 @@ def check_determinant(self): >>> HillCipher(numpy.matrix([[2,5],[1,6]])).check_determinant() >>> """ - det = round(numpy.linalg.det(self.encrypt_key)) + det: int = round(numpy.linalg.det(self.encrypt_key)) if det < 0: det = det % len(self.key_string) @@ -110,8 +110,8 @@ def process_text(self, text): 'TESTINGHILLCIPHERR' >>> """ - text = list(text.upper()) - text = [char for char in text if char in self.key_string] + text: list = list(text.upper()) + text: list = [char for char in text if char in self.key_string] last = text[-1] while len(text) % self.break_key != 0: @@ -147,10 +147,10 @@ def make_decrypt_key(self): matrix([[ 6., 25.], [ 5., 26.]]) """ - det = round(numpy.linalg.det(self.encrypt_key)) + det: int = round(numpy.linalg.det(self.encrypt_key)) if det < 0: - det = det % len(self.key_string) + det: int = det % len(self.key_string) det_inv = None for i in range(len(self.key_string)): if (det * i) % len(self.key_string) == 1: @@ -208,7 +208,7 @@ def decrypt(self, text): WHXYJOLM9C6XT085LL """ N = int(input("Enter the order of the encryption key: ")) - hill_matrix = [] + hill_matrix: list = [] print("Enter each row of the encryption key with space separated integers") for i in range(N): From 6889ec1b40091c53adecbce1cfdacbe60639a915 Mon Sep 17 00:00:00 2001 From: Marvin Michum Date: Mon, 13 Apr 2020 00:07:35 -0400 Subject: [PATCH 4/4] spacing --- ciphers/hill_cipher.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ciphers/hill_cipher.py b/ciphers/hill_cipher.py index 053539e46206..6aeb8b1b80a9 100644 --- a/ciphers/hill_cipher.py +++ b/ciphers/hill_cipher.py @@ -144,8 +144,8 @@ def encrypt(self, text): def make_decrypt_key(self): """ >>> HillCipher(numpy.matrix([[2,5],[1,6]])).make_decrypt_key() - matrix([[ 6., 25.], - [ 5., 26.]]) + matrix([[ 6., 25.], + [ 5., 26.]]) """ det: int = round(numpy.linalg.det(self.encrypt_key))