Chris Nauroth
Welcome About Me Diary Software Downloads About the Site
Introduction
www.cnauroth.net
WebSlinger
Mancala
Base64Converter
LogAnalyzer
Permutations

Base64Converter

Download the source code.

Near the end of my time working for St. Paul Travelers, I had a conversation with a co-worker dealing with a piece of software that needed to work with Base64-encoded data. I got curious about Base64, and ultimately, I wound up writing a Java utility that can perform the encoding and decoding.

Base64 Encoding Algorithm

Base64 encodes 3 8-bit binary bytes into 4 6-bit characters. The source bits are rearranged into the following destination bits of the characters:

                 Byte 1   Byte 2   Byte 3
                
11111122 22223333 33444444

(The number indicates which of the 4 characters receives the bit.) If the source length is not divisible by 3, then it will not be possible to encode the last source bytes as a group of 4 characters. In this case, the equals sign ('=') is used as a padding character at the end of the result. Each line of encoded text is 72 characters long, and each line terminates with a carriage return and line feed (CR/LF). For additional information about Base64 encoding, refer to RFC1113.

Implementation

I was brushing up on Java and design patterns when I wrote this. Part of the algorithm needs to map integer values to character values. I encapsulated this in a Base64Map class. I chose the Singleton pattern, so that the memory would be allocated only once within the same process and reused across multiple uses.

The user interface needs to toggle between encoding files and decoding files. Both of these actions take an input stream, manipulate the input data, and write the results to an output stream. I defined a StreamStrategy interface to represent an interaction between an input stream and an output stream. The user interface holds a reference to a StreamStrategy and toggles it between referencing 2 specific implementations: Base64EncodeStrategy and Base64DecodeStrategy.

To implement the actual encoding and decoding algorithms, I chose to extend InputStream and OutputStream. A Base64OutputStream encodes data as it is written to the stream. Likewise, a Base64InputStream can read a stream of data that has been Base64-encoded and decode it as the client reads.

The user interface ties it all together, using the Swing API. I defined a few helper classes to assist with layout tasks and displaying an HTML help file in a dialog.

Future Plans

It's actually been a while since I worked with this code. I was working with Java 1.4 at the time. It might be interesting to see if anything would benefit from using Java 1.5 features, like generics.