forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add running key cipher (TheAlgorithms#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 <[email protected]>
- Loading branch information
1 parent
6b588e4
commit d59cf17
Showing
1 changed file
with
75 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
""" | ||
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. | ||
: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) | ||
ciphertext = [] | ||
ord_a = 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)) | ||
|
||
return "".join(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) | ||
plaintext = [] | ||
ord_a = 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)) | ||
|
||
return "".join(plaintext) | ||
|
||
|
||
def test_running_key_encrypt() -> None: | ||
""" | ||
>>> key = "How does the duck know that? said Victor" | ||
>>> ciphertext = running_key_encrypt(key, "DEFEND THIS") | ||
>>> running_key_decrypt(key, ciphertext) == "DEFENDTHIS" | ||
True | ||
""" | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() | ||
test_running_key_encrypt() | ||
|
||
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) | ||
print(f"{encrypted_text = }") | ||
|
||
decrypted_text = running_key_decrypt(key, encrypted_text) | ||
print(f"{decrypted_text = }") |