8000 Create keyword_cipher.py · GitHubberFitz/ScriptsDump@46d3b82 · GitHub
[go: up one dir, main page]

Skip to content

Commit 46d3b82

Browse files
Create keyword_cipher.py
1 parent c4913c3 commit 46d3b82

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
'''
2+
Python Implementation Of Keyword Cipher
3+
Author : Mohit Kumar
4+
5+
A keyword cipher is a form of monoalphabetic substitution. A keyword is used as the key, and it determines the letter matchings of the cipher alphabet
6+
to the plain alphabet.Repeats of letters in the word are removed, then the cipher alphabet is generated with the keyword matching to A, B, C etc
7+
8+
'''
9+
10+
def remove_duplicates(key: str) -> str:
11+
"""
12+
Removes duplicate alphabetic characters in a keyword (letter is ignored after its
13+
first appearance).
14+
:param key: Keyword to use
15+
:return: String with duplicates removed
16+
>>> remove_duplicates('Hello World!!')
17+
'Helo Wrd'
18+
"""
19+
20+
key_no_dups = ""
21+
for ch in key:
22+
if ch == " " or ch not in key_no_dups and ch.isalpha():
23+
key_no_dups += ch
24+
return key_no_dups
25+
26+
27+
def create_cipher_map(key: str) -> dict:
28+
"""
29+
Returns a cipher map given a keyword.
30+
:param key: keyword to use
31+
:return: dictionary cipher map
32+
"""
33+
# Create alphabet list
34+
alphabet = [chr(i + 65) for i in range(26)]
35+
# Remove duplicate characters from key
36+
key = remove_duplicates(key.upper())
37+
offset = len(key)
38+
# First fill cipher with key characters
39+
cipher_alphabet = {alphabet[i]: char for i, char in enumerate(key)}
40+
# Then map remaining characters in alphabet to
41+
# the alphabet from the beginning
42+
for i in range(len(cipher_alphabet), 26):
43+
char = alphabet[i - offset]
44+
# Ensure we are not mapping letters to letters previously mapped
45+
while char in key:
46+
offset -= 1
47+
char = alphabet[i - offset]
48+
cipher_alphabet[alphabet[i]] = char
49+
return cipher_alphabet
50+
51+
52+
def encipher(message: str, cipher_map: dict) -> str:
53+
"""
54+
Enciphers a message given a cipher map.
55+
:param message: Message to encipher
56+
:param cipher_map: Cipher map
57+
:return: enciphered string
58+
>>> encipher('Hello World!!', create_cipher_map('Goodbye!!'))
59+
'CYJJM VMQJB!!'
60+
"""
61+
return "".join(cipher_map.get(ch, ch) for ch in message.upper())
62+
63+
64+
def decipher(message: str, cipher_map: dict) -> str:
65+
"""
66+
Deciphers a message given a cipher map
67+
:param message: Message to decipher
68+
:param cipher_map: Dictionary mapping to use
69+
:return: Deciphered string
70+
>>> cipher_map = create_cipher_map('Goodbye!!')
71+
>>> decipher(encipher('Hello World!!', cipher_map), cipher_map)
72+
'HELLO WORLD!!'
73+
"""
74+
# Reverse our cipher mappings
75+
rev_cipher_map = {v: k for k, v in cipher_map.items()}
76+
return "".join(rev_cipher_map.get(ch, ch) for ch in message.upper())
77+
78+
79+
def main():
80+
"""
81+
Handles I/O
82+
:return: void
83+
"""
84+
message = input("Enter message to encode or decode: ").strip()
85+
key = input("Enter keyword: ").strip()
86+
option = input("Encipher or decipher? E/D:").strip()[0].lower()
87+
try:
88+
func = {"e": encipher, "d": decipher}[option]
89+
except KeyError:
90+
raise KeyError("invalid input option")
91+
cipher_map = create_cipher_map(key)
92+
print(func(message, cipher_map))
93+
94+
95+
if __name__ == "__main__":
96+
import doctest
97+
98+
doctest.testmod()
99+
main()

0 commit comments

Comments
 (0)
0