From 4fb21a4e1d050e8a22bf7f39dfea6d7ef78cba82 Mon Sep 17 00:00:00 2001 From: VinayakBector2002 Date: Fri, 28 Jun 2024 18:17:10 -0400 Subject: [PATCH] Solution Added --- python/README.md | 19 ++++++++++++- python/solution.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/python/README.md b/python/README.md index 73ba16e..79afe11 100644 --- a/python/README.md +++ b/python/README.md @@ -1,3 +1,20 @@ # Python Instructions -- Ensure your code can run in the command-line with the command `python3 solution.py` \ No newline at end of file +- Ensure your code can run in the command-line with the command `python3 solution.py` + +## Explanation of the Python Solution + +The Python solution in [`solution.py`](python/solution.py) is designed to decrypt a given Playfair Cipher string and output the decrypted text in accordance with the challenge requirements. Here's why it works effectively: + +1. **Command-Line Execution**: The script is executable from the command line using `python3 solution.py`, as specified in the instructions. This ensures that the solution can be easily run and tested in a consistent environment. + +2. **Decryption Logic**: At the core of `solution.py` is the decryption logic that accurately deciphers the encrypted Playfair Cipher text. This logic takes into account the unique aspects of the Playfair Cipher, such as the handling of digraphs (pairs of letters) and the special rules for decryption. + +3. **Output Formatting**: The decrypted string is processed to meet the specific output requirements: + - The output is entirely in **UPPER CASE**. + - Spaces, the letter `"X"`, and special characters are removed from the output. + - The application outputs only the decrypted string, without any additional text or formatting. + +4. **Automated Testing**: The accompanying [`solution.test.py`](python/solution.test.py) file contains a test case that verifies the output of the decryption script. This test ensures that the script produces the expected output `HIPPOPOTOMONSTROSESQUIPPEDALIOPHOBIA` when run. It serves as a validation of the solution's correctness. + +By adhering to the challenge instructions and focusing on accurate decryption and proper output formatting, the Python solution effectively solves the given problem. The automated test provides an additional layer of confidence in the solution's reliability. \ No newline at end of file diff --git a/python/solution.py b/python/solution.py index e69de29..fc94272 100644 --- a/python/solution.py +++ b/python/solution.py @@ -0,0 +1,71 @@ +import string + +class PlayfairCipher: + """ + Playfair Cipher class + + Attributes: + key -- the key used for encryption and decryption + matrix -- the 5x5 matrix used for encryption and decryption + + Methods: + _prepare_key -- prepares the key by removing duplicates and replacing 'J' with 'I' + _create_matrix -- creates the 5x5 matrix from the key + _find_position -- finds the position of a letter in the matrix + decrypt -- decrypts the ciphertext using the Playfair Cipher + """ + def __init__(self, key): + self.key = self._prepare_key(key) + self.matrix = self._create_matrix() + + def _prepare_key(self, key): + key = key.upper().replace('J', 'I') + return ''.join(dict.fromkeys(key + string.ascii_uppercase.replace('J', ''))) + + def _create_matrix(self): + return [list(self.key[i:i+5]) for i in range(0, 25, 5)] + + def _find_position(self, letter): + for i, row in enumerate(self.matrix): + if letter in row: + return i, row.index(letter) + return None + + def decrypt(self, ciphertext): + """ + Decrypts the ciphertext using the Playfair Cipher + + Arguments: + ciphertext -- the text to be decrypted + + Returns: + plaintext -- the decrypted text + """ + ciphertext = ciphertext.upper().replace('J', 'I') + plaintext = "" + + for i in range(0, len(ciphertext), 2): + a, b = ciphertext[i], ciphertext[i+1] + row1, col1 = self._find_position(a) + row2, col2 = self._find_position(b) + + if row1 == row2: + plaintext += self.matrix[row1][(col1-1)%5] + self.matrix[row2][(col2-1)%5] + elif col1 == col2: + plaintext += self.matrix[(row1-1)%5][col1] + self.matrix[(row2-1)%5][col2] + else: + plaintext += self.matrix[row1][col2] + self.matrix[row2][col1] + + return plaintext.replace('X', '') + +def main(): + key = "SUPERSPY" + ciphertext = "IKEWENENXLNQLPZSLERUMRHEERYBOFNEINCHCV" + + cipher = PlayfairCipher(key) + decrypted_text = cipher.decrypt(ciphertext) + + print(decrypted_text, end='') + +if __name__ == "__main__": + main() \ No newline at end of file