idontcare
idontcare

Reputation: 29

Substitution Cipher in Python with a Letter Map

I want to do Substitution Cipher but have a letter map instead of the letters being random. So far my code only randomizes it and doesn't use the letter map, because I don't know how to do that.

#Substitution Cipher
def subst_cipher(alphabet):
   alphabet = list(alphabet)
   letter_map = {'a': 'm', 'b': 'k', 'c': 'n', 'd': 'o', 'e': 'c', 'f': 'v', 'g': 'w', 'h': 'z', 'i': 'b', 'j': 't', 'k': 'y', 'l': 'r', 'm': 'x', 'n': 'd', 'o': 'u', 'p': 'p', 'q': 'a', 'r': 'i', 's': 's', 't': 'f', 'u': 'q', 'v': 'e', 'w': 'l', 'x': 'g', 'y': 'j', 'z': 'h'}
   random.shuffle(alphabet)
   return ''.join(alphabet)

Test Cases:

#What it should do
subst_cipher(letter_map,'Figaro')
returns: 'vbwmmu # I think
#what it does now
subst_cipher('Figaro')
returns: 'oaFirg'

help!

Upvotes: 0

Views: 379

Answers (1)

AKX
AKX

Reputation: 169338

You can use "".join() and a generator expression to map each letter in the string using the substitution table.

def subst_cipher(letter_map, text):
    return "".join(letter_map.get(c, "?") for c in text)

I've chosen to replace letters not in the map with ? instead of crashing outright (letter_map[c]).

Calling this with your letter map from above:

letter_map = {
    "a": "m",
    "b": "k",
    # ... elided for brevity...
}

print(subst_cipher(letter_map, "figaro"))

outputs

vbwmiu

which is more or less what you expected.

Upvotes: 1

Related Questions