Skip to content

Commit d34b9e1

Browse files
Merge branch 'TheAlgorithms:master' into TheAlgorithms#9611-Serialize_and_Deserialize
2 parents 0c410f5 + 937ce83 commit d34b9e1

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

Diff for: ciphers/fractionated_morse_cipher.py

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
"""
2+
Python program for the Fractionated Morse Cipher.
3+
4+
The Fractionated Morse cipher first converts the plaintext to Morse code,
5+
then enciphers fixed-size blocks of Morse code back to letters.
6+
This procedure means plaintext letters are mixed into the ciphertext letters,
7+
making it more secure than substitution ciphers.
8+
9+
http://practicalcryptography.com/ciphers/fractionated-morse-cipher/
10+
"""
11+
import string
12+
13+
MORSE_CODE_DICT = {
14+
"A": ".-",
15+
"B": "-...",
16+
"C": "-.-.",
17+
"D": "-..",
18+
"E": ".",
19+
"F": "..-.",
20+
"G": "--.",
21+
"H": "....",
22+
"I": "..",
23+
"J": ".---",
24+
"K": "-.-",
25+
"L": ".-..",
26+
"M": "--",
27+
"N": "-.",
28+
"O": "---",
29+
"P": ".--.",
30+
"Q": "--.-",
31+
"R": ".-.",
32+
"S": "...",
33+
"T": "-",
34+
"U": "..-",
35+
"V": "...-",
36+
"W": ".--",
37+
"X": "-..-",
38+
"Y": "-.--",
39+
"Z": "--..",
40+
" ": "",
41+
}
42+
43+
# Define possible trigrams of Morse code
44+
MORSE_COMBINATIONS = [
45+
"...",
46+
"..-",
47+
"..x",
48+
".-.",
49+
".--",
50+
".-x",
51+
".x.",
52+
".x-",
53+
".xx",
54+
"-..",
55+
"-.-",
56+
"-.x",
57+
"--.",
58+
"---",
59+
"--x",
60+
"-x.",
61+
"-x-",
62+
"-xx",
63+
"x..",
64+
"x.-",
65+
"x.x",
66+
"x-.",
67+
"x--",
68+
"x-x",
69+
"xx.",
70+
"xx-",
71+
"xxx",
72+
]
73+
74+
# Create a reverse dictionary for Morse code
75+
REVERSE_DICT = {value: key for key, value in MORSE_CODE_DICT.items()}
76+
77+
78+
def encode_to_morse(plaintext: str) -> str:
79+
"""Encode a plaintext message into Morse code.
80+
81+
Args:
82+
plaintext: The plaintext message to encode.
83+
84+
Returns:
85+
The Morse code representation of the plaintext message.
86+
87+
Example:
88+
>>> encode_to_morse("defend the east")
89+
'-..x.x..-.x.x-.x-..xx-x....x.xx.x.-x...x-'
90+
"""
91+
return "x".join([MORSE_CODE_DICT.get(letter.upper(), "") for letter in plaintext])
92+
93+
94+
def encrypt_fractionated_morse(plaintext: str, key: str) -> str:
95+
"""Encrypt a plaintext message using Fractionated Morse Cipher.
96+
97+
Args:
98+
plaintext: The plaintext message to encrypt.
99+
key: The encryption key.
100+
101+
Returns:
102+
The encrypted ciphertext.
103+
104+
Example:
105+
>>> encrypt_fractionated_morse("defend the east","Roundtable")
106+
'ESOAVVLJRSSTRX'
107+
108+
"""
109+
morse_code = encode_to_morse(plaintext)
110+
key = key.upper() + string.ascii_uppercase
111+
key = "".join(sorted(set(key), key=key.find))
112+
113+
# Ensure morse_code length is a multiple of 3
114+
padding_length = 3 - (len(morse_code) % 3)
115+
morse_code += "x" * padding_length
116+
117+
fractionated_morse_dict = {v: k for k, v in zip(key, MORSE_COMBINATIONS)}
118+
fractionated_morse_dict["xxx"] = ""
119+
encrypted_text = "".join(
120+
[
121+
fractionated_morse_dict[morse_code[i : i + 3]]
122+
for i in range(0, len(morse_code), 3)
123+
]
124+
)
125+
return encrypted_text
126+
127+
128+
def decrypt_fractionated_morse(ciphertext: str, key: str) -> str:
129+
"""Decrypt a ciphertext message encrypted with Fractionated Morse Cipher.
130+
131+
Args:
132+
ciphertext: The ciphertext message to decrypt.
133+
key: The decryption key.
134+
135+
Returns:
136+
The decrypted plaintext message.
137+
138+
Example:
139+
>>> decrypt_fractionated_morse("ESOAVVLJRSSTRX","Roundtable")
140+
'DEFEND THE EAST'
141+
"""
142+
key = key.upper() + string.ascii_uppercase
143+
key = "".join(sorted(set(key), key=key.find))
144+
145+
inverse_fractionated_morse_dict = dict(zip(key, MORSE_COMBINATIONS))
146+
morse_code = "".join(
147+
[inverse_fractionated_morse_dict.get(letter, "") for letter in ciphertext]
148+
)
149+
decrypted_text = "".join(
150+
[REVERSE_DICT[code] for code in morse_code.split("x")]
151+
).strip()
152+
return decrypted_text
153+
154+
155+
if __name__ == "__main__":
156+
"""
157+
Example usage of Fractionated Morse Cipher.
158+
"""
159+
plaintext = "defend the east"
160+
print("Plain Text:", plaintext)
161+
key = "ROUNDTABLE"
162+
163+
ciphertext = encrypt_fractionated_morse(plaintext, key)
164+
print("Encrypted:", ciphertext)
165+
166+
decrypted_text = decrypt_fractionated_morse(ciphertext, key)
167+
print("Decrypted:", decrypted_text)

0 commit comments

Comments
 (0)