From 960ff5d8af82f29ff577da596aed463fda44420a Mon Sep 17 00:00:00 2001 From: ArshdeepSingh98 Date: Mon, 23 Oct 2023 02:21:17 -0700 Subject: [PATCH 1/5] Add running key cipher --- ciphers/running_key_cipher.py | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 ciphers/running_key_cipher.py diff --git a/ciphers/running_key_cipher.py b/ciphers/running_key_cipher.py new file mode 100644 index 000000000000..c31e82bdebba --- /dev/null +++ b/ciphers/running_key_cipher.py @@ -0,0 +1,39 @@ +def running_key_encrypt(key, plaintext): + plaintext = plaintext.replace(" ", "").upper() + key = key.replace(" ", "").upper() + key_length = len(key) + ciphertext = [] + + for i in range(len(plaintext)): + p = ord(plaintext[i]) - ord("A") + k = ord(key[i % key_length]) - ord("A") + c = (p + k) % 26 + ciphertext.append(chr(c + ord("A"))) + + return "".join(ciphertext) + + +def running_key_decrypt(key, ciphertext): + ciphertext = ciphertext.replace(" ", "").upper() + key = key.replace(" ", "").upper() + key_length = len(key) + plaintext = [] + + for i in range(len(ciphertext)): + c = ord(ciphertext[i]) - ord("A") + k = ord(key[i % key_length]) - ord("A") + p = (c - k) % 26 + plaintext.append(chr(p + ord("A"))) + + return "".join(plaintext) + + +if __name__ == "__main__": + key = "How does the duck know that? said Victor" + plaintext = input("Enter the plaintext: ").upper() + encrypted_text = running_key_encrypt(key, plaintext) + decrypted_text = running_key_decrypt(key, encrypted_text) + + print("\nPlaintext:", plaintext) + print("Encrypted:", encrypted_text) + print("Decrypted:", decrypted_text) From 0de53b9e6a5d5b943911853b26877b56f0adc6f0 Mon Sep 17 00:00:00 2001 From: ArshdeepSingh98 Date: Mon, 23 Oct 2023 02:28:34 -0700 Subject: [PATCH 2/5] update running key cipher add doctests and hints --- ciphers/running_key_cipher.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ciphers/running_key_cipher.py b/ciphers/running_key_cipher.py index c31e82bdebba..a2ab17256050 100644 --- a/ciphers/running_key_cipher.py +++ b/ciphers/running_key_cipher.py @@ -1,4 +1,11 @@ -def running_key_encrypt(key, plaintext): +def running_key_encrypt(key: str, plaintext: str) -> str: + """ + Encrypts the plaintext using the Running Key Cipher. + + :param key: The running key (long piece of text). + :param plaintext: The plaintext to be encrypted. + :return: The ciphertext. + """ plaintext = plaintext.replace(" ", "").upper() key = key.replace(" ", "").upper() key_length = len(key) @@ -13,7 +20,14 @@ def running_key_encrypt(key, plaintext): return "".join(ciphertext) -def running_key_decrypt(key, ciphertext): +def running_key_decrypt(key: str, ciphertext: str) -> str: + """ + Decrypts the ciphertext using the Running Key Cipher. + + :param key: The running key (long piece of text). + :param ciphertext: The ciphertext to be decrypted. + :return: The plaintext. + """ ciphertext = ciphertext.replace(" ", "").upper() key = key.replace(" ", "").upper() key_length = len(key) From 1bf84c4e34b5f981c3c47d34f4864845eae10f7e Mon Sep 17 00:00:00 2001 From: ArshdeepSingh98 Date: Mon, 23 Oct 2023 02:43:15 -0700 Subject: [PATCH 3/5] Add test case --- ciphers/running_key_cipher.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ciphers/running_key_cipher.py b/ciphers/running_key_cipher.py index a2ab17256050..fddbef10bc3b 100644 --- a/ciphers/running_key_cipher.py +++ b/ciphers/running_key_cipher.py @@ -42,7 +42,23 @@ def running_key_decrypt(key: str, ciphertext: str) -> str: return "".join(plaintext) +def test_running_key_encrypt(): + """ + >>> key = "How does the duck know that? said Victor" + >>> plaintext = "DEFEND THIS" + >>> ciphertext = running_key_encrypt(key, plaintext) + >>> decrypted_text = running_key_decrypt(key, ciphertext) + >>> decrypted_text == "DEFENDTHIS" + True + """ + + if __name__ == "__main__": + import doctest + + doctest.testmod() + test_running_key_encrypt() + key = "How does the duck know that? said Victor" plaintext = input("Enter the plaintext: ").upper() encrypted_text = running_key_encrypt(key, plaintext) From ed55cfc40e53374f1cf9a8b903d0980343c40701 Mon Sep 17 00:00:00 2001 From: ArshdeepSingh98 Date: Mon, 23 Oct 2023 02:45:33 -0700 Subject: [PATCH 4/5] Update return value --- ciphers/running_key_cipher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ciphers/running_key_cipher.py b/ciphers/running_key_cipher.py index fddbef10bc3b..e1b0b878b47d 100644 --- a/ciphers/running_key_cipher.py +++ b/ciphers/running_key_cipher.py @@ -42,7 +42,7 @@ def running_key_decrypt(key: str, ciphertext: str) -> str: return "".join(plaintext) -def test_running_key_encrypt(): +def test_running_key_encrypt() -> None: """ >>> key = "How does the duck know that? said Victor" >>> plaintext = "DEFEND THIS" From d41b9da81949ac7f15c0b88947fb9d4e6e62fb37 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 29 Oct 2023 15:49:55 +0100 Subject: [PATCH 5/5] range(len()) is almost always a hint to use enumerate() --- ciphers/running_key_cipher.py | 40 ++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/ciphers/running_key_cipher.py b/ciphers/running_key_cipher.py index e1b0b878b47d..6bda417be898 100644 --- a/ciphers/running_key_cipher.py +++ b/ciphers/running_key_cipher.py @@ -1,3 +1,8 @@ +""" +https://en.wikipedia.org/wiki/Running_key_cipher +""" + + def running_key_encrypt(key: str, plaintext: str) -> str: """ Encrypts the plaintext using the Running Key Cipher. @@ -10,12 +15,13 @@ def running_key_encrypt(key: str, plaintext: str) -> str: key = key.replace(" ", "").upper() key_length = len(key) ciphertext = [] + ord_a = ord("A") - for i in range(len(plaintext)): - p = ord(plaintext[i]) - ord("A") - k = ord(key[i % key_length]) - ord("A") + for i, char in enumerate(plaintext): + p = ord(char) - ord_a + k = ord(key[i % key_length]) - ord_a c = (p + k) % 26 - ciphertext.append(chr(c + ord("A"))) + ciphertext.append(chr(c + ord_a)) return "".join(ciphertext) @@ -32,12 +38,13 @@ def running_key_decrypt(key: str, ciphertext: str) -> str: key = key.replace(" ", "").upper() key_length = len(key) plaintext = [] + ord_a = ord("A") - for i in range(len(ciphertext)): - c = ord(ciphertext[i]) - ord("A") - k = ord(key[i % key_length]) - ord("A") + for i, char in enumerate(ciphertext): + c = ord(char) - ord_a + k = ord(key[i % key_length]) - ord_a p = (c - k) % 26 - plaintext.append(chr(p + ord("A"))) + plaintext.append(chr(p + ord_a)) return "".join(plaintext) @@ -45,10 +52,8 @@ def running_key_decrypt(key: str, ciphertext: str) -> str: def test_running_key_encrypt() -> None: """ >>> key = "How does the duck know that? said Victor" - >>> plaintext = "DEFEND THIS" - >>> ciphertext = running_key_encrypt(key, plaintext) - >>> decrypted_text = running_key_decrypt(key, ciphertext) - >>> decrypted_text == "DEFENDTHIS" + >>> ciphertext = running_key_encrypt(key, "DEFEND THIS") + >>> running_key_decrypt(key, ciphertext) == "DEFENDTHIS" True """ @@ -59,11 +64,12 @@ def test_running_key_encrypt() -> None: doctest.testmod() test_running_key_encrypt() - key = "How does the duck know that? said Victor" plaintext = input("Enter the plaintext: ").upper() + print(f"\n{plaintext = }") + + key = "How does the duck know that? said Victor" encrypted_text = running_key_encrypt(key, plaintext) - decrypted_text = running_key_decrypt(key, encrypted_text) + print(f"{encrypted_text = }") - print("\nPlaintext:", plaintext) - print("Encrypted:", encrypted_text) - print("Decrypted:", decrypted_text) + decrypted_text = running_key_decrypt(key, encrypted_text) + print(f"{decrypted_text = }")