I've reversed the following algorithm from a challenge binary I'm investigating:
def encrypt(plain):
l = len(plain)
a = 10
cipher = ""
for i in range(0, l):
if i + a < l - 1:
cipher += chr( xor(plain[i], plain[i+a]) )
else:
cipher += chr( xor(plain[i], plain[a]) )
if ord(plain[i]) % 2 == 0: a += 1 # even
else: a -= 1 # odd
return cipher
from binascii import hexlify
print hexlify(encrypt("this is a test string"))
Essentially, it XORs each character with another character in the string, offset by a
. a
initial value is 10
, as the function iterates over the characters in the string, a +=1
if the character's value is even or a -= 1
if it's odd.
I've worked out in my head how to reverse this cipher and retrieve plain text, it would require the use of a recursive function to find out which character offsets are even/odd in the original string. IE: Given the properties of XOR % 2, we now that if cipher[0]
is odd then either plain[0]
or plain[10]
is odd, but not both. Similarly if cipher[0]
is even then both plain[0]
and plain[10]
are even, or both are odd. From there a recursive algorithm should be able to work the rest.
Once we know which characters in plaintext are even/odd, reversing the rest is trivial. I've spent a few hours working this out, but now I'm at loss implementing it.
I've used basic recursive algorithms in the past but never anything that "branches out" to solve something like this.
Given a cipher
string resulting from this function, how could we use a recursive algorithm to determine the parity of each character in the original plain string?
EDIT: Sorry just to be clear and in response to a comment, after scratching my head on this for a few hours I thought the recursion strategy outlined above would be the only way to solve this. If not I'm open to any hints/assistance to solving the title question.