Reputation: 61
I have a script which 'encodes' user entered text, for now it's just a string 'python' by default. I am having a problem decoding it.
This is the output with f.tell, where I can see it only reads first byte from each row and outputs only 'pto' instead of 'python'.
2
p2
2
2
t2
2
2
o2
2
2
Traceback (most recent call last):
File "...\file.py", line 73, in <module>
oa=ord(a)
TypeError: ord() expected a character, but string of length 0 found
>>>
Somehow it reads without a problem until string of length 0 is found, I can't found where because text.bin is equally spaced, just like key.bin.
Running xxd -b on text.bin file shows that file contains necessary bytes for decoding.
00000000: 00000000 00000000 01110000 00000000 00000000 01111001 ..p..y
00000006: 00000000 00000000 01110100 00000000 00000000 01101000 ..t..h
0000000c: 00000000 00000000 01101111 00000000 00000000 01101110 ..o..n
00000012: 00000000 00000000 ..
Also key.bin contains them. Here first byte(odd) is an offset between each char in text.bin and second byte (even) is an XOR mask. I set it to 0 because I haven't thought of a method to generate symetrical bytes to do xor at the end. I guess I would need XOR cipher for this..
00000000: 00000010 00000000 00000010 00000000 00000010 00000000 ......
00000006: 00000010 00000000 00000010 00000000 00000010 00000000 ......
0000000c: 00000010 00000000 00000010 00000000 00000010 00000000 ......
00000012: 00000010 00000000 00000010 00000000 00000010 00000000 ......
00000018: 00000010 .
Here is the current code
fdata = open("text.bin","wb") ; fmeta = open("key.bin","w+b")
print('Enter a text:')
txt='python' # input()
print('Binary:')
print(" ".join(txt))
l=len(txt)
print(l, 'bytes')
strtobin= ' '.join(format(x, 'b') for x in bytearray(txt, 'utf-8'))
print(strtobin)
shift=int(2)
sh=nobv.to_bytes(1, byteorder='big')
# even bytes in key.bin
for v in range(0, 25, 2): # len(txt)
#print(v)
fmeta.seek(v)
fmeta.write(sh)
# odd bytes in key.bin (contains first part for XOR)
for a in range(0,25): #len(txt)+1
if a % 2 != 0:
#print(a)
fmeta.seek(a)
fmeta.write(b'\x00')
pad = b'\x00\00'
for line in txt:
for char in line:
fdata.write(pad)
fdata.write(char.encode())
fdata.write(pad)
fdata.close() ; fmeta.close()
f = open ("key.bin", "rb"); d = open ("text.bin", "rb")
f.seek(0); d.seek(0) ; position = 0
while 1:
#f.seek(2,0)
offset = f.read(1)
f.seek(1,0)
mask = f.read(1)
if not offset: break;
if not mask: break;
shift = int(ord(offset))
position = position + shift
d.seek(position)
print(f.tell())
a = d.read(1)
oa=ord(a)
om=ord(mask)
output = chr(oa^om)
print (output, end="")
f.close() ; d.close()
Upvotes: 2
Views: 153
Reputation: 626
Your script looked like something I could help with, so I thought I'd give it the old college try.
First problem is at line 15: you didn't define "sh"; also, the way you wrote your "in range" block will not work on a lot of systems, so I made it look more like your other loop.
for v in range(0, 25):
if v % 2 == 0:
#print(v)
fmeta.seek(v)
fmeta.write(sh)
I'm not sure what you're using that variable for, specifically, so I just added the line
sh = b'\x01'
to the list of variables at the top while I as testing the script. Figure it'd make it easy to spot what the script is actually doing, later.
Now, at this point, I get the error
oa=ord(a)
TypeError: ord() expected a character, but string of length 0 found
I suspect the issue is with these two lines:
38: offset = f.read(1)
, and
45: shift = int(ord(offset))
Your program is reading the offset from your file "key.bin", and then stepping that far over into the file "text.bin", and when it goes to a = d.read(1)
, sometimes it's reading EOF or a null value.
I'm not entirely sure how to fix the script, here, because I don't understand what your goal output is, but I hope I was able to help, anyway :)
Upvotes: 1