Skip to content

Commit d59cf17

Browse files
Add running key cipher (#10834)
* Add running key cipher * update running key cipher add doctests and hints * Add test case * Update return value * range(len()) is almost always a hint to use enumerate() --------- Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent 6b588e4 commit d59cf17

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

ciphers/running_key_cipher.py

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""
2+
https://en.wikipedia.org/wiki/Running_key_cipher
3+
"""
4+
5+
6+
def running_key_encrypt(key: str, plaintext: str) -> str:
7+
"""
8+
Encrypts the plaintext using the Running Key Cipher.
9+
10+
:param key: The running key (long piece of text).
11+
:param plaintext: The plaintext to be encrypted.
12+
:return: The ciphertext.
13+
"""
14+
plaintext = plaintext.replace(" ", "").upper()
15+
key = key.replace(" ", "").upper()
16+
key_length = len(key)
17+
ciphertext = []
18+
ord_a = ord("A")
19+
20+
for i, char in enumerate(plaintext):
21+
p = ord(char) - ord_a
22+
k = ord(key[i % key_length]) - ord_a
23+
c = (p + k) % 26
24+
ciphertext.append(chr(c + ord_a))
25+
26+
return "".join(ciphertext)
27+
28+
29+
def running_key_decrypt(key: str, ciphertext: str) -> str:
30+
"""
31+
Decrypts the ciphertext using the Running Key Cipher.
32+
33+
:param key: The running key (long piece of text).
34+
:param ciphertext: The ciphertext to be decrypted.
35+
:return: The plaintext.
36+
"""
37+
ciphertext = ciphertext.replace(" ", "").upper()
38+
key = key.replace(" ", "").upper()
39+
key_length = len(key)
40+
plaintext = []
41+
ord_a = ord("A")
42+
43+
for i, char in enumerate(ciphertext):
44+
c = ord(char) - ord_a
45+
k = ord(key[i % key_length]) - ord_a
46+
p = (c - k) % 26
47+
plaintext.append(chr(p + ord_a))
48+
49+
return "".join(plaintext)
50+
51+
52+
def test_running_key_encrypt() -> None:
53+
"""
54+
>>> key = "How does the duck know that? said Victor"
55+
>>> ciphertext = running_key_encrypt(key, "DEFEND THIS")
56+
>>> running_key_decrypt(key, ciphertext) == "DEFENDTHIS"
57+
True
58+
"""
59+
60+
61+
if __name__ == "__main__":
62+
import doctest
63+
64+
doctest.testmod()
65+
test_running_key_encrypt()
66+
67+
plaintext = input("Enter the plaintext: ").upper()
68+
print(f"\n{plaintext = }")
69+
70+
key = "How does the duck know that? said Victor"
71+
encrypted_text = running_key_encrypt(key, plaintext)
72+
print(f"{encrypted_text = }")
73+
74+
decrypted_text = running_key_decrypt(key, encrypted_text)
75+
print(f"{decrypted_text = }")

0 commit comments

Comments
 (0)