Author Topic: How might one convert a BINARY FILE to a base64 string?  (Read 2066 times)

I have these lovely functions by truce, but I have no idea how to use them on a non-ascii file, such as an image.

The best idea I can come up with is doing this:

Code: [Select]
%file = new fileObject();
%file.openForRead(%filepath);
while(!%file.isEOF())
$allfile = $allfile @ %file.readline();
%file.close();
%file.delete();

However, due to the fact that openForRead opens it in an ascii format (?), it won't read properly, and will give me the same gibberish as if I had opened it in a text editor.
What alternatives do I have?

Code: [Select]
////////////////////////////////////////
//  Base64 Pack             by Truce  //
////////////////////////////////////////

function convertBase(%val,%atype,%btype)
{
%vlen = strLen(%val);
%alen = strLen(%atype);
%blen = strLen(%btype);

for(%i = 0; %i < %vlen; %i++)
%sum += striPos(%atype,getSubStr(%val,%i,1)) * mPow(%alen,%vlen - %i - 1);

while(1)
{
%rem = %sum % %blen;
%new = getSubStr(%btype,%rem,1) @ %new;
%sum = mFloor(%sum / %blen);

if(!%sum)
break;
}

return %new;
}

function base64Encode(%str)
{
%base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
%asciimap  = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN" @
             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

%len = strLen(%str);

for(%i = 0; %i < %len; %i++)
{
%chr   = getSubStr(%str,%i,1);
%ascii = strPos(%asciimap,%chr) + 32;
%bin   = convertBase(%ascii,"0123456789","01");

while(strLen(%bin) < 8)
%bin = "0" @ %bin;

%all = %all @ %bin;
}

%len = strLen(%all);

for(%i = 0; %i < %len; %i += 6)
{
%pack = getSubStr(%all,%i,6);

while(strLen(%pack) < 6)
%pack = %pack @ "0";

%dec = convertBase(%pack,"01","0123456789");
%new = %new @ getSubStr(%base64map,%dec,1);
}

while(strLen(%new) % 4 > 0)
%new = %new @ "=";

return %new;
}

function base64Decode(%str)
{
%base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
%asciimap  = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN" @
             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

while(getSubStr(%str,strLen(%str) - 1,1) $= "=")
%str = getSubStr(%str,0,strLen(%str) - 1);

%len = strLen(%str);

for(%i = 0; %i < %len; %i++)
{
%chr = getSubStr(%str,%i,1);
%pos = strPos(%base64map,%chr);
%bin = convertBase(%pos,"0123456789","01");

while(strLen(%bin) < 6)
%bin = "0" @ %bin;

%all = %all @ %bin;
}

while(strLen(%all) % 8 > 0)
%all = getSubStr(%all,0,strLen(%all) - 1);

%len = strLen(%all);

for(%i = 0; %i < %len; %i += 8)
{
%bin = getSubStr(%all,%i,8);
%dec = convertBase(%bin,"01","0123456789") - 32;
%chr = getSubStr(%asciiMap,%dec,1);

%new = %new @ %chr;
}

return %new;
}

It gives you proper binary. It shows up as "nonsense" because echo interprets it as characters.

so I could do this, assuming the above functions are defined
Code: [Select]
function getBinaryFile(%filepath)
{
if(!isFile(%filepath))
{
messageClient(%client, '', "Error 404");
return;
}
%file = new fileObject();
%file.openForRead(%filepath);
while(!%file.isEOF())
%filecontents = %filecontents @ %file.readline();
%file.close();
%file.delete();
%binary = base64Encode(%fileContents);
return %binary;
}

Then I could send this over a TCP object connection to another client/server that can decode base64 and I'm golden?

Edit, could you host a webserver, then have a webpage that only contains a base64 encoded file, then download said webpage, then decode it allowing transfer of files?

  • I'm uncertain if file objects write binary properly.
  • You cannot have byte 0x00 in a string.

  • I'm uncertain if file objects write binary properly.
  • You cannot have byte 0x00 in a string.
1) time for testing I guess
2) well stuff, is there any way to read/write it or anything at all? What if the file doesn't contain that character anywhere in it?

If the file doesn't contain 0x00, you're fine to go. Otherwise you're screwed.

If the file doesn't contain 0x00, you're fine to go. Otherwise you're screwed.
I assume I can't check for this, it simply won't be there when I decode?

I assume I can't check for this, it simply won't be there when I decode?

If you try to load 0xF3 0xDD 0x00 0xA2, it'll most likely end up as 0xF3 0xDD.

If you try to load 0xF3 0xDD 0x00 0xA2, it'll most likely end up as 0xF3 0xDD.
... it'll stop?

well stuff. that isn't helpful.


why is torquescript like that? can it cause crashes or some stuff?

... it'll stop?

well stuff. that isn't helpful.


why is torquescript like that? can it cause crashes or some stuff?

"because it's easier for us" - kompressor

so I just used a default base64 conversion program in the linux distro i'm on on the attached picture, got this output

http://pastebin.com/raw.php?i=zamXunXK

I took said output, decoded it with the same program, and the picture turned out fine.

When I encoded the same image with the base64encode function posted in the OP, it gave me an entirely different string, which could not be decoded with the program in the distro.

Next tests:
encode string with PROGRAM, decode with torque
encode string with torque, decode with torque
retry encoding with torque, decode with program
« Last Edit: June 15, 2012, 04:50:38 AM by Lugnut1206 »

result; encoded with torque, decoded with program

didn't work. randomly, I decided to check it in a text editor

turns out it has no /r/n line return things anywhere, its just one big string, unlike the correct .png, which has returns all over the place. this might be why it isn't turning up properly.

encode with torque, decode with torque
...
the file vanished? the source encoded file remained, but the decoded copy seems to have never been created.

attempting encode with program, decode with torque...


crashed the server. beautiful. no it lagged processing it, I'm getting forgetloads of errors now...
error pertains to getSubStr... starting position must be greater than 0, starting position is -32.
what tha fack
« Last Edit: June 15, 2012, 05:05:47 AM by Lugnut1206 »

result; encoded with torque, decoded with program

didn't work. randomly, I decided to check it in a text editor

turns out it has no /r/n line return things anywhere, its just one big string, unlike the correct .png, which has returns all over the place. this might be why it isn't turning up properly.

encode with torque, decode with torque
...
the file vanished? the source encoded file remained, but the decoded copy seems to have never been created.

attempting encode with program, decode with torque...


crashed the server. beautiful. no it lagged processing it, I'm getting forgetloads of errors now...
error pertains to getSubStr... starting position must be greater than 0, starting position is -32.
what tha fack

Post your code.


why is torquescript like that? can it cause crashes or some stuff?
Because in traditional C derived languages (which Torque is built on) an 0x00 byte, also known as the null character, is placed in a string in order to signify that the string is ended. It has to be like this, because in C a string is just a block of characters (bytes) and there is no reference to the actual length of a string, so instead it just traverses the block of characters until it hits a null character, which it assumes is the end of the string.

So when you read the bytes in a file, the file reader assumes you are reading a text file and stores the bytes into a string, so any null characters (0x00) will trigger the string to be cut off, so anything after the null character is ignored.

The PNG specification uses the null character for separation sections of the file: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html

So you can't use Torque to read the file unless there is some unheard of way to read a file without Torque turning it into an ASCII string. Attempting to base64 encode or decode will result in a different or malformed base64 string because data has been lost.