44599

Reverse engineer Ceasar cipher

<h3>Question</h3>

I reverse engineered to decrypt, but do not get the expected result.

For example, entering

<pre class="lang-none prettyprint-override">Lipps${svph%

with offset 4 should result in

<pre class="lang-none prettyprint-override">Hello World!

but I get

<pre class="lang-none prettyprint-override">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)
<h3>Answer1:</h3>

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

<h3>lower and upper bounds</h3>

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.

<h2>final version</h2>

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)
<h3>Answer2:</h3>

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.

<pre class="lang-py prettyprint-override">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

Recommend