BASE 64 Decoding and Encoding Class 2003
Environment: VC6 SP4, NT4 SP3, Win95 and above, Win2k and above
Introduction
After publishing my POP3 class in 2001, lots of e-mails reached me. Most people were not asking for a problem or reporting bugs but they asked me how to de- or encode Base64 data. I think at the beginning of 2002 a new virus spread around the world. It was using a bug in MS Outlook that executed attached files automatically. I wanted to know how it works to protect my computer properly. That was the day when I decided to write my own Base64 class for decoding and encoding data out and into the Base64 format because I wanted to write a mail filter tool.
Sources
The Base64 format is decribed in RFC 2045 in part 6.8 called "Base64 Content-Transfer-Encoding." It explains all rules that must be followed to write a proper Base64 coder. This means "The encoded output stream must be represented in lines of no more than 76" and so on... Here is a link to this RFC. http://www.faqs.org/ftp/rfc/rfc2045.txt
Abilities
My Base64 class can decode and encode data in and out of the Base64 format. You can decode Base64 data in two ways. You can decode a whole file containing Base64 data or you can pass a buffer to the class that contains the Base64 data. Encoding works the same. Per file or per buffer as wanted and needed. The class works no matter how much data you pass or how huge the files are. The only thing you need to take care of is to reserve enough memory.
Sample
Below I will explain all four cases of de- and encoding Base64 data with my class. You can download the source of this class and use it. The only thing I would like to ask you is to reference at this class in the Info screen of your app, maybe, but that's up to you.
Contact Information
If you have problems using the class or want to tell me of improvements and so forth, feel free to mail me. I am still improving the class and optimizing it, so there may be updates in the near future.
Samples
Case 1: You want to decode a Base64-encoded application with the file name "test.b64" and store the decoded application in "test.exe".
CBase64 B64;
B64.DecodeFile ("test.b64", "test.exe");
Case 2: You want to decode a Base64-encoded buffer and store the decoded data in another buffer. This case is a bit more complicated. Base64-encoded data is around 30% larger in size than normal data. This means you do not need a buffer that is as large as the buffer containing the Base64 data. This is solved for you with the CreateMatchingDecodingBuffer function. The first Parameter of this function is the address of the buffer that holds the data that you want to decode. The second parameter is an address to a char* that will receive the adress of a matching decoding buffer. DO NOT FORGET to delete this buffer as soon as you do not need it any more. Here, pInput is the buffer that contains the Base64 data.
char* pDecodedDataBuffer;
B64.CreateMatchingDecodingBuffer (pInput, &pDecodedDataBuffer);
B64.DecodeBuffer (pInput, pDecodedDataBuffer);
//...use the decoded data write it to a file etc. ...
delete pDecodedDataBuffer;
Case 3: You want to encode a file into Base64 and store the decoded data in the file in "test.b64".
CBase64 B64;
B64.EncodeFile ("test.exe", "test.b64");
Case 4: You want to encode a buffer and store the encoded data in another buffer. This case is a bit more complicated than just encoding a file. Encoding a buffer means that your encoded data will be around 30% larger than your source data. To create a buffer that is capable of holding all the encoded data, you can call CreateMatchingEncodingBuffer. The function takes two parameters. The first parameter tells the function how many bytes there are in your buffer that need to be encoded. The second parameter is is the address to a char* that will be filled by the function with the address of a matching buffer for the encoded data. DO NOT FORGET to delete pInput as soon as you do not need it any more. In this sample, pInput contains 114 bytes that I want to be encoded. At first, I create a matching buffer by calling CreateMatchingEncodingBuffer. Then, I pass pInput and pB64Output to EncodeBuffer and tell it that there are 114 bytes to encode in pInput. The function now converts the bytes from pInput to Base64 and stores the result in pB64Output.
char* pB64Output;
B64.CreateMatchingEncodingBuffer (pInput, &pB64Output);
B64.EncodeBuffer (pInput, 114, pB64Output);
//... process the encoded data write it to a file, etc.
delete pInput;

Comments
Thanks for such a great code!
Posted by ppkumar_74 on 09/13/2007 04:12amDear Sir, I am a novice in programming and i need to use base64 program to encode and decode and i found your source pretty helpful.i am very thankful to you.sir kindly allow me to use your code into my project.i would be really greatful if you allowed me to do so. Thanking you, praveen
ReplyBug fix during decoding data with length no divisible by 4
Posted by petro_nm on 03/15/2005 11:21am-
ReplyIs this fix correct?
Posted by KaramChand03 on 02/17/2006 07:44amIs this the correct fix? I would like to use this class but just saw this message. If this is the correct fix then I will go ahead and do it.
ReplyBug Fix
Posted by Legacy on 02/12/2004 12:00amOriginally posted by: Jan
Hello,
thanks for the hint.
I have not yet tested it. I figured to have a problem with special file sizes a few days ago though.
I am sure that will fix it.
Sorry for not posting updates on this class
but I have been busy with my rl programming job.
Take care
ReplyJan
Bug in CBase64::DecodeBuffer(...)
Posted by Legacy on 02/09/2004 12:00amOriginally posted by: Rhys Ziemer
-
ReplyException when call DecodeFile
Posted by cklam on 10/13/2004 10:43pm//the test.txt contain the following text "I am Anthony Do you see me" CBase64 B64; B64.EncodeFile ("test.txt", "test.b64"); //store encode data to file "test.b64" B64.DecodeFile ("test.b64", "test.bat"); But when it call the DecodeFile , the DecodeFile throw execption Please check it, thank you for your help!ReplyBug Fix
Posted by Legacy on 12/17/2003 12:00amOriginally posted by: Jan
Hi Rhys,
thanks for the good work.
I think you are right.
I haven't worked on the Base64 Class
since posting the article.
I will hopefully have the time to update the class
and deliver some more efficient routines
to encode and decode data.
Merry Christmas
Jan
ReplyBug in CBase64::DecodeBuffer(...)
Posted by Legacy on 12/12/2003 12:00amOriginally posted by: Rhys Ziemer
ReplyDo you know...
Posted by Legacy on 09/29/2003 12:00amOriginally posted by: Manuel
Hello Jan,
Do you know how to compile your Cbase64 class in Borland C++ 6.0 or other free class on internet???
Thanks for all!
ReplyDoes the job, but isn't very CPU efficient
Posted by Legacy on 09/08/2003 12:00amOriginally posted by: Code2Go
Your solution performs allot of shifting about (<<s and >>s). The task can be accomplished with less shifts and smaller ones as well. I don't mean to be picky, but it could be crucial for performance critical applications. Other than this, good job Jan!
ReplyYou are create ;-))
Posted by Legacy on 08/24/2003 12:00amOriginally posted by: Marcel Beutner
A class like this(soooo easy to use), I have ever searched.
Thak you ;-))
ReplyPerfect job
Posted by Legacy on 07/16/2003 12:00amOriginally posted by: Sohail Pakistani
Works absolutely fine. Thanks for sharing the code with community.
ReplyRegards,
Sohail Pakistani
Loading, Please Wait ...