@
rachhost I've reversed the
big()
function (as @
deanhystad has also done, I think) and I'm sure that we'll have different code for this.
The method I've used is to construct three functions, each one taking the input from the preceding one, in the reverse order in which
big()
encoded the string.
big("Testing this decoder.")
Output:
Big output: yohoxc+en%ndn+blbx_
Output:
Stage one decode output: ynodhno+xbc+lebxn_%
Stage two decode output: redoced siht gnitseT.
Stage three decode output: Testing this decoder.
So, I'll now work on the rest of this and see if I can achieve the goal.
So, to recap...
def big(data):
o = ''
f = (data[-1] + data[:-1])[::-1] # feeding the output back in to this, reverses the operation
for i in f: # passes each character in f to the function below
o += chr(ord(i) ^ 0xb) # chr() is the reverse of ord(), so again feeding the output back in to this, reverses the operation
return o[::2]+ o[1::2] # I had to construct a loop routine to reverse this, but there may be other ways.
The only real challenge here (for me), was the
return
as I could not reverse the
o[::2]+ o[1::2]
operation without constructing a loop routine, but as this is a reversing operation, it's the first thing that needs to be done in order to reverse the
big()
function. Again (as in my first post) using a none repeating sequence as the input, one can better understand what is happening:
d = '0123456789'
x = d[::2]
y = d[1::2]
z = x+y
print('d:',d)
print('x:',x)
print('y:',y)
print('x + y:', z)
Output:
d: 0123456789
x: 02468
y: 13579
x + y: 0246813579
edit done for code comments and typos
Note: This thread may now be a out of sequence, @
rachhost has yet to come back with any code, but moving forward...
For this part, I wanted to write a decoder that does not use the
string
library.
So,
if c not in string.ascii_letters:
becomes
if not c.isalpha():
and
if c in string.ascii_lowercase:
becomes
if c.islower():
def bang(data,shift): # data is a string object and shift is a integer value
enc = ''
for c in data:
if not c.isalpha():
enc += c
else:
if c.islower():
start = ord('a')
else:
start = ord('A')
enc += chr(((ord(c) - start + shift) % 26) + start)
return enc[-1] + enc[:-1].swapcase()
That aside...
Again, working in reverse, we first need to deconstruct
return enc[-1] + enc[:-1].swapcase()
enc
is constructed in the
for
loop, which in turn, does not alter anything that is not an alpha character, so an easy test for the
return
, is to pass a none repeating numeric sequence to
bang()
and see what it does.
d = "0123456789"
s = 0
x = bang(d, s)
print(x)
Output:
9012345678
So, it seems to simply swap the first and last characters of a numeric string; let's test that by doing the same on the input and break apart the
return
:
d = "1234567890"
x = d[-1]
y = d[:-1]
z = x+y
print('x' ,x)
print('y' ,y)
print('z', z)
Output:
x 0
y 123456789
z 0123456789
Confirmed.
I then did some more tests by adding in a alpha character (both uppercase and lowercase) at various positions, to see what results I got.
<some time later>
While playing around with different inputs, I got to thinking: what if (as before) I simply feed the output back in again, for as many times as there are characters in the input, and see what happens.
In doing that, I discovered that, for an even number of characters, the character case is reversed, but not for an odd number of characters. So it follows that running the routine twice, will always return the input.
data = "This is a line of text."
s = 0
print(f"Length: {len(data)}\n")
data_in = data
print(f"Loop 1 data: {data_in}")
for run in range(len(data)):
data_out =(bang(data_in, s))
print(f"run{run}: {data_out}")
data_in = data_out
data_in = data_out
print(f"\nLoop 2 data: {data_in}")
for run in range(len(data)):
data_out =(bang(data_in, s))
print(f"run{run}: {data_out}")
data_in = data_out
print(data_out))
I'll not post the output here, as it's over 50 lines long. The entire output is only really needed if you want to see what's happening, but simply comment out the
print()
functions within the loops to reduce that.
So, I think that the
bang()
function can be used against itself; no need for a rewrite, but I'll continue testing and see if I'm correct.
Now for the 'shift' in the
bang()
function
for c in data:
loop.
This puts me in mind of a 'Rotation cipher', which is a very simple form of encryption, which is performed by shifting the alpha characters by a predetermined number of places (search for Rot13 for some details on that). This, together with the
XOR
operation that we see in the
big()
function, seems to be the key to how all of this hangs together.
If that's correct, then a simple
52 -
the shift, would get us back to the starting point. I see that the first 'shift' is
18
(have a look at the
check()
function) so
52 - 18 = 34
; let's test this by introducing a shift in (by 18) and a shift out (by 34).
data = "This is a line of text."
data_in = data
shift_in = 18
for run in range(len(data)):
data_out = (bang(data_in, shift_in))
data_in = data_out
data_in = data_out
for run in range(len(data)):
data_out = (bang(data_in, shift_in))
data_in = data_out
print(data_out)
#=======================================#
data_in = data_out
shift_out = 52 - shift_in
for run in range(len(data)):
data_out = (bang(data_in, shift_out))
data_in = data_out
data_in = data_out
for run in range(len(data)):
data_out = (bang(data_in, shift_out))
data_in = data_out
print(data_out)
Nailed it!
With what we have here, it seems to me that all that remains is to glue these bits together, in the correct order, and it's job done.
I've yet to do this, so it could turn out that I've messed up somewhere; we'll see.
I'll refrain from posting any more code, unless I've made a huge error which would be too misleading for this thread to be of any help, but I'll try and answer any questions, should there be any.
I may have got a little ahead of myself here, as the decode of
bang()
with a shift seems to be broken, but it's close. I may simply re-code it, rather than try to fudge a fix.