HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Monoalphabetic Substitution Cipher

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
monoalphabeticsubstitutioncipher

Problem

In light of this months Community Challenge, I've taken a stab at building something related. Keep in mind, this isn't a submission for the challenge, just a utility to help in the later process of completing the challenge.

What we have here is your simple encryption and decryption (with a given key) tool. I'd like to know if what I have is the most efficient, the most well written, and the simplest form of these functions.

import random

alpha = "abcdefghijklmnopqrstuvwxyz"

def encrypt(original, key=None):

    if key is None:
        l = list(alpha)
        random.shuffle(l)
        key = "".join(l)

    new = []

    for letter in original:
        new.append(key[alpha.index(letter)])

    return ["".join(new), key]

def decrypt(cipher, key=None):
    if key is not None:
        new = []
        for letter in cipher:
            new.append(alpha[key.index(letter)])

        return "".join(new)
    # we'll have an else here for the actual Community Challenge!


I'm nowhere near an expert with Python, so if I'm not following coding standards, please guide me there too.

A simple test might be:

e = encrypt("helloworld", None)
print(e)
print(decrypt(e[0], e[1]))


and we'd get something along the lines of:

['wussndnkst', 'qxvtupaweroslynzhkbigcdjmf']
helloworld

Solution

"abcdefghijklmnopqrstuvwxyz" is just the constant string.ascii_lowercase.

Whenever you have this pattern:

some_list = []
for dummy in some_iterable:
    some_list.append(some_function_of(dummy))


… that's a candidate for replacement with a list comprehension.

alpha.index(letter) and its inverse could be a performance issue when processing longer messages. Making a dictionary for the translation table would be better. Note that any character that is not ASCII lowercase will cause a ValueError. For encrypt(),

translation = dict(zip(key, string.ascii_lowercase))
ciphertext = ''.join(translation.get(c, c) for c in original)


Here, translation.get(c, c) causes unrecognized characters to be passed through. You can use translation[c] to restore the original exception-raising behaviour.

Code Snippets

some_list = []
for dummy in some_iterable:
    some_list.append(some_function_of(dummy))
translation = dict(zip(key, string.ascii_lowercase))
ciphertext = ''.join(translation.get(c, c) for c in original)

Context

StackExchange Code Review Q#92779, answer score: 4

Revisions (0)

No revisions yet.