Reverse engineer Ceasar cipher

和自甴很熟 提交于 2020-06-15 20:09:12

问题


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 did I do wrong?

code = input("Enter text to decrypt: ")
distance = int(input("Enter number of offset: "))
plainText = ''
for ch in code:
    ordValue = ord(ch)
    cipherValue = ordValue - distance
    if cipherValue < ord('a'):
        cipherValue = ord('z') - \
            (distance - (ord('a') - ordValue + 1))
    plainText += chr(cipherValue)
print(plainText)

回答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)
    if exp == 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)



回答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.

def caesar(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!'


来源:https://stackoverflow.com/questions/60795235/reverse-engineer-ceasar-cipher

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!