Ryan
Ryan

Reputation: 71

Python decryption

I am currently working on a homework assignment, and we have to build a function where we make a three step encryption/decryption program. One of the ciphers we have to build is a transposition/rail fence that takes a variable (n) as a number of "rails" that you'd like to have the message encrypted in. I've built the encryption, but I'm at a loss of the decryption method.

This is for an intro level class to python, so we don't know too much beyond the basics like the encryption code that is included below.

If you're not sure what I mean by transposition encrypt/rail fence is here's an example...

Message = abcdefg
n = 3

It'd end up being encrypted into 3 groups (as noted by n) and those groups would be "adg be cf" and from there the encryption recombines them into one string "adgbecf". My trouble is breaking them back down into the original three strings of "adg be cf" and then transposing them back to the original values.

Encryption:

def trans_encrypt(message, n):
    cipher = ""
    for i in range(n):
        for j in range(i, len(message), n):
            cipher = cipher + message[j]
    return cipher

Current decryption (doesn't work):

def trans_decrypt(cipher, n):
    length = len(cipher) // n
    message = ''
    for i in range(length): 
        for j in range(n):
            letter = (i + j * length) 
            message = message + cipher[letter] 
    return message

Upvotes: 3

Views: 4743

Answers (2)

Lisa
Lisa

Reputation: 11

The problem is that the cipher is not necessarily evenly divisible by n, so your 'bins' created by the encrypt function are not all of the same length. The first len(cipher)%n bins have one extra letter.

When you iterate over j in the decrypt function, if i is less than len(cipher)%n the range should be n+1.

Upvotes: 1

dting
dting

Reputation: 39287

If your encryption method is correct, (someone commented that this isn't a rail cypher), the following is true:

You can do your encrypt like so:

>>> def trans_encrypt(message,n):
...     return "".join([message[i::n] for i in range(n)])
... 
>>> trans_encrypt(a,3)
'adgbecf'

I'll give you a hint about your decryption:

>>> b = 'adgbe cf '
>>> trans_encrypt(b,3)
'abcdefg  '

I inserted spaces into the "encrpyted" string and just used the encrypt method on the "encrypted" string to decrypt it. I got the right result with some extra expected spaces at the end.

I'll let you figure out how to calculate where to add the spaces since this is homework.

Your decrypt method can just modify the message (inserting spaces), call your encrypt method, and strip the trailing white space.

Upvotes: 3

Related Questions