Skip to content

Commit 3f8b2af

Browse files
VictorRS27pre-commit-ci[bot]cclauss
authored
Add autoclave cipher (TheAlgorithms#8029)
* Add autoclave cipher * Update autoclave with the given suggestions * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixing errors * Another fixes * Update and rename autoclave.py to autokey.py * Rename gaussian_naive_bayes.py to gaussian_naive_bayes.py.broken.txt * Rename gradient_boosting_regressor.py to gradient_boosting_regressor.py.broken.txt * Rename random_forest_classifier.py to random_forest_classifier.py.broken.txt * Rename random_forest_regressor.py to random_forest_regressor.py.broken.txt * Rename equal_loudness_filter.py to equal_loudness_filter.py.broken.txt Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <[email protected]>
1 parent 30277f8 commit 3f8b2af

6 files changed

+131
-0
lines changed

ciphers/autokey.py

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
"""
2+
https://en.wikipedia.org/wiki/Autokey_cipher
3+
An autokey cipher (also known as the autoclave cipher) is a cipher that
4+
incorporates the message (the plaintext) into the key.
5+
The key is generated from the message in some automated fashion,
6+
sometimes by selecting certain letters from the text or, more commonly,
7+
by adding a short primer key to the front of the message.
8+
"""
9+
10+
11+
def encrypt(plaintext: str, key: str) -> str:
12+
"""
13+
Encrypt a given plaintext (string) and key (string), returning the
14+
encrypted ciphertext.
15+
>>> encrypt("hello world", "coffee")
16+
'jsqqs avvwo'
17+
>>> encrypt("coffee is good as python", "TheAlgorithms")
18+
'vvjfpk wj ohvp su ddylsv'
19+
>>> encrypt("coffee is good as python", 2)
20+
Traceback (most recent call last):
21+
...
22+
TypeError: key must be a string
23+
>>> encrypt("", "TheAlgorithms")
24+
Traceback (most recent call last):
25+
...
26+
ValueError: plaintext is empty
27+
"""
28+
if not isinstance(plaintext, str):
29+
raise TypeError("plaintext must be a string")
30+
if not isinstance(key, str):
31+
raise TypeError("key must be a string")
32+
33+
if not plaintext:
34+
raise ValueError("plaintext is empty")
35+
if not key:
36+
raise ValueError("key is empty")
37+
38+
key += plaintext
39+
plaintext = plaintext.lower()
40+
key = key.lower()
41+
plaintext_iterator = 0
42+
key_iterator = 0
43+
ciphertext = ""
44+
while plaintext_iterator < len(plaintext):
45+
if (
46+
ord(plaintext[plaintext_iterator]) < 97
47+
or ord(plaintext[plaintext_iterator]) > 122
48+
):
49+
ciphertext += plaintext[plaintext_iterator]
50+
plaintext_iterator += 1
51+
elif ord(key[key_iterator]) < 97 or ord(key[key_iterator]) > 122:
52+
key_iterator += 1
53+
else:
54+
ciphertext += chr(
55+
(
56+
(ord(plaintext[plaintext_iterator]) - 97 + ord(key[key_iterator]))
57+
- 97
58+
)
59+
% 26
60+
+ 97
61+
)
62+
key_iterator += 1
63+
plaintext_iterator += 1
64+
return ciphertext
65+
66+
67+
def decrypt(ciphertext: str, key: str) -> str:
68+
"""
69+
Decrypt a given ciphertext (string) and key (string), returning the decrypted
70+
ciphertext.
71+
>>> decrypt("jsqqs avvwo", "coffee")
72+
'hello world'
73+
>>> decrypt("vvjfpk wj ohvp su ddylsv", "TheAlgorithms")
74+
'coffee is good as python'
75+
>>> decrypt("vvjfpk wj ohvp su ddylsv", "")
76+
Traceback (most recent call last):
77+
...
78+
ValueError: key is empty
79+
>>> decrypt(527.26, "TheAlgorithms")
80+
Traceback (most recent call last):
81+
...
82+
TypeError: ciphertext must be a string
83+
"""
84+
if not isinstance(ciphertext, str):
85+
raise TypeError("ciphertext must be a string")
86+
if not isinstance(key, str):
87+
raise TypeError("key must be a string")
88+
89+
if not ciphertext:
90+
raise ValueError("ciphertext is empty")
91+
if not key:
92+
raise ValueError("key is empty")
93+
94+
key = key.lower()
95+
ciphertext_iterator = 0
96+
key_iterator = 0
97+
plaintext = ""
98+
while ciphertext_iterator < len(ciphertext):
99+
if (
100+
ord(ciphertext[ciphertext_iterator]) < 97
101+
or ord(ciphertext[ciphertext_iterator]) > 122
102+
):
103+
plaintext += ciphertext[ciphertext_iterator]
104+
else:
105+
plaintext += chr(
106+
(ord(ciphertext[ciphertext_iterator]) - ord(key[key_iterator])) % 26
107+
+ 97
108+
)
109+
key += chr(
110+
(ord(ciphertext[ciphertext_iterator]) - ord(key[key_iterator])) % 26
111+
+ 97
112+
)
113+
key_iterator += 1
114+
ciphertext_iterator += 1
115+
return plaintext
116+
117+
118+
if __name__ == "__main__":
119+
import doctest
120+
121+
doctest.testmod()
122+
operation = int(input("Type 1 to encrypt or 2 to decrypt:"))
123+
if operation == 1:
124+
plaintext = input("Typeplaintext to be encrypted:\n")
125+
key = input("Type the key:\n")
126+
print(encrypt(plaintext, key))
127+
elif operation == 2:
128+
ciphertext = input("Type the ciphertext to be decrypted:\n")
129+
key = input("Type the key:\n")
130+
print(decrypt(ciphertext, key))
131+
decrypt("jsqqs avvwo", "coffee")

0 commit comments

Comments
 (0)