同步操作将从 编程语言算法集/Python 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
"""Hill Cipher:The 'HillCipher' class below implements the Hill Cipher algorithm which usesmodern linear algebra techniques to encode and decode text using an encryptionkey matrix.Algorithm:Let the order of the encryption key be N (as it is a square matrix).Your text is divided into batches of length N and converted to numerical vectorsby a simple mapping starting with A=0 and so on.The key is then multiplied with the newly created batch vector to obtain theencoded vector. After each multiplication modular 36 calculations are performedon the vectors so as to bring the numbers between 0 and 36 and then mapped withtheir corresponding alphanumerics.While decrypting, the decrypting key is found which is the inverse of theencrypting key modular 36. The same process is repeated for decrypting to getthe original message back.Constraints:The determinant of the encryption key matrix must be relatively prime w.r.t 36.Note:This implementation only considers alphanumerics in the text. If the length ofthe text to be encrypted is not a multiple of the break key(the length of onebatch of letters), the last character of the text is added to the text until thelength of the text reaches a multiple of the break_key. So the text afterdecrypting might be a little different than the original text.References:https://apprendre-en-ligne.net/crypto/hill/Hillciph.pdfhttps://www.youtube.com/watch?v=kfmNeskzs2ohttps://www.youtube.com/watch?v=4RhLNDqcjpA"""import stringimport numpydef greatest_common_divisor(a: int, b: int) -> int:""">>> greatest_common_divisor(4, 8)4>>> greatest_common_divisor(8, 4)4>>> greatest_common_divisor(4, 7)1>>> greatest_common_divisor(0, 10)10"""return b if a == 0 else greatest_common_divisor(b % a, a)class HillCipher:key_string = string.ascii_uppercase + string.digits# This cipher takes alphanumerics into account# i.e. a total of 36 characters# take x and return x % len(key_string)modulus = numpy.vectorize(lambda x: x % 36)to_int = numpy.vectorize(lambda x: round(x))def __init__(self, encrypt_key: numpy.ndarray) -> None:"""encrypt_key is an NxN numpy array"""self.encrypt_key = self.modulus(encrypt_key) # mod36 calc's on the encrypt keyself.check_determinant() # validate the determinant of the encryption keyself.break_key = encrypt_key.shape[0]def replace_letters(self, letter: str) -> int:""">>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))>>> hill_cipher.replace_letters('T')19>>> hill_cipher.replace_letters('0')26"""return self.key_string.index(letter)def replace_digits(self, num: int) -> str:""">>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))>>> hill_cipher.replace_digits(19)'T'>>> hill_cipher.replace_digits(26)'0'"""return self.key_string[round(num)]def check_determinant(self) -> None:""">>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))>>> hill_cipher.check_determinant()"""det = round(numpy.linalg.det(self.encrypt_key))if det < 0:det = det % len(self.key_string)req_l = len(self.key_string)if greatest_common_divisor(det, len(self.key_string)) != 1:raise ValueError(f"determinant modular {req_l} of encryption key({det}) is not co prime "f"w.r.t {req_l}.\nTry another key.")def process_text(self, text: str) -> str:""">>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))>>> hill_cipher.process_text('Testing Hill Cipher')'TESTINGHILLCIPHERR'>>> hill_cipher.process_text('hello')'HELLOO'"""chars = [char for char in text.upper() if char in self.key_string]last = chars[-1]while len(chars) % self.break_key != 0:chars.append(last)return "".join(chars)def encrypt(self, text: str) -> str:""">>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))>>> hill_cipher.encrypt('testing hill cipher')'WHXYJOLM9C6XT085LL'>>> hill_cipher.encrypt('hello')'85FF00'"""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]vec = [self.replace_letters(char) for char in batch]batch_vec = numpy.array([vec]).Tbatch_encrypted = self.modulus(self.encrypt_key.dot(batch_vec)).T.tolist()[0]encrypted_batch = "".join(self.replace_digits(num) for num in batch_encrypted)encrypted += encrypted_batchreturn encrypteddef make_decrypt_key(self) -> numpy.ndarray:""">>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))>>> hill_cipher.make_decrypt_key()array([[ 6, 25],[ 5, 26]])"""det = round(numpy.linalg.det(self.encrypt_key))if det < 0:det = det % len(self.key_string)det_inv = Nonefor i in range(len(self.key_string)):if (det * i) % len(self.key_string) == 1:det_inv = ibreakinv_key = (det_inv* numpy.linalg.det(self.encrypt_key)* numpy.linalg.inv(self.encrypt_key))return self.to_int(self.modulus(inv_key))def decrypt(self, text: str) -> str:""">>> hill_cipher = HillCipher(numpy.array([[2, 5], [1, 6]]))>>> hill_cipher.decrypt('WHXYJOLM9C6XT085LL')'TESTINGHILLCIPHERR'>>> hill_cipher.decrypt('85FF00')'HELLOO'"""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]vec = [self.replace_letters(char) for char in batch]batch_vec = numpy.array([vec]).Tbatch_decrypted = self.modulus(decrypt_key.dot(batch_vec)).T.tolist()[0]decrypted_batch = "".join(self.replace_digits(num) for num in batch_decrypted)decrypted += decrypted_batchreturn decrypteddef main() -> None:N = int(input("Enter the order of the encryption key: "))hill_matrix = []print("Enter each row of the encryption key with space separated integers")for _ in range(N):row = [int(x) for x in input().split()]hill_matrix.append(row)hc = HillCipher(numpy.array(hill_matrix))print("Would you like to encrypt or decrypt some text? (1 or 2)")option = input("\n1. Encrypt\n2. Decrypt\n")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":text_d = input("What text would you like to decrypt?: ")print("Your decrypted text is:")print(hc.decrypt(text_d))if __name__ == "__main__":import doctestdoctest.testmod()main()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。