Skip to content Skip to sidebar Skip to footer

Reverse Engineer Ceasar Cipher

I reverse engineered to decrypt, but do not get the expected result. For example, entering Lipps${svph% with offset 4 should result in Hello World! but I get ello´world³ What

Solution 1:

OK, I got it working for a-z and gave you a little test framework to enter/check automatically rather than typing it in every time.

def dowork(code, distance, lower, upper):


    bounddown, boundup = ord(lower), ord(upper)

    plaintext = ""for ch in code:
        ordValue = ord(ch)
        cipherValue = ordValue - distance
        if cipherValue < bounddown:
            cipherValue = boundup - bounddown - ordValue +1

        plaintext += chr(cipherValue)


    return plaintext

dataexp = [
    (("jgnnq",2, 'a', 'z'),"hello"),
    ]

for input_, exp in dataexp:
    got = dowork(*input_)
    msg = "exp:%s:%s:got for %s" % (exp, got, inp)
    ifexp == got:
        print("good! %s" % msg)
    else:
        print("bad ! %s" % msg)

This prints

good! exp:hello:hello:got for('jgnnq', 2, 'a', 'z')

Now all you need to do is add an extra item to the dataexp list, something like

(("Lipps${svph%", 4, <lowerbound>, <upperbound char>), "Hello World!")

once you have the upper and lower bound figured out it should work. Notice that I didn't know caesar code, I just copied yours directly but restructured it a bit.

what *_input does is to take those 4 values in that tuple (more or less a list) and assign them to code, distance, lower, upper in the dowork function.

lower is what corresponds to a in your code and upper is z.

exp is what you expect and exp == got just checks whether what the function returned is correct or not. once you get the function correct it should work for both my simplistic a-z, 2 distance, hello test and your more complicated 4 distance but including punctuation

lower and upper bounds

your 2 strings, input and output, are Lipps${svph% and Hello World!. That means all of these characters need to fall within your upper and lower ord values, right? So the minimum ord position of all those is your lower and the max is your upper. Now, I'm not the guy from Cryptonomicon and I can't ever remember if ord(a) < ord(A) or not, let alone the punctuations. So you'll have to kind tinker with that, which is why I based my test on only the lower case letters. I'd add 0-9 though.

final version

This does not need you to figure out which character to put at lowest bound and which at upper. We take lower = 32 (start of printable chars), upper = 255. That way punctuations, upper and lower case, digits, their ord values dont matter anymore.

#full ASCII range, you can go to town on entering whatever you want
bounddown, boundup = 32, 255

plaintext = ""for ch in code:
    ordValue = ord(ch)
    cipherValue = ordValue - distance
    if cipherValue < bounddown:
        cipherValue = boundup - bounddown - ordValue +1

    plaintext += chr(cipherValue)

Solution 2:

Here's a implementation for encrypting and decrypting when the input for characters within a certain range (in this case a-z). You can adapt this for other ranges depending on what you need.

defcaesar(text, offset, decrypt=False):
    lower_bound, upper_bound = ord('a'), ord('z')
    if decrypt:
        offset = (upper_bound - lower_bound + 1) - offset
    result = ''for t in text:
        o = ord(t)
        if lower_bound <= o <= upper_bound:
            new_t = o + offset
            if new_t > upper_bound:
                new_t = (new_t % upper_bound) + lower_bound - 1
            result += chr(new_t)
        else:
           result += t
    return result

Then you can call:

caesar(caesar('hello world!', 2,), 2, True)
# => 'hello world!'

Post a Comment for "Reverse Engineer Ceasar Cipher"