Base64 : Converting Binary Data to ASCII Text

Posted on Friday, July 25, 2008

3


The origin of Base64 may have many stories like it was invented to transfer 8-bit data over systems which could not handle 8 bits.

The uses of Base64 have prevalently been in transferring images as email attachments, transferring non English characters over the internet, converting Binary data to text etc.

My particular need for Base64 came into picture when we were processing a SOAP response. The SOAP response was processed and put into a Map. Now we were required to store this Map into a database CLOB field. Had it been a BLOB I would have pushed the Map in. This is when my friend and fellow colleague Pankaj Misra suggested Base64 encoding to me.

What is Base64?

Image courtesy wikipedia

As you can see in the image for any word 3 bytes are joined together to form 24 bits. These 24 bits are then grouped into packs of 6 bits. Now the ASCII value of these 6 bits is taken and a new word is made. Hence Man gets encoded as TWFu.

One should be aware that Base64 is not encryption. Agreed that the text becomes unreadable but can be easily decoded back.

Base 64 encoding

public class Base64 {
 public static String base64code =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
  "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/";
 public static int splitLinesAt = 76;
 public static String base64Encode(String string) {
  String encoded = "";
  // determine how many padding bytes to add to the output
  int paddingCount = (3 - (string.length() % 3)) % 3;
  // add any necessary padding to the input
  string += "".substring(0, paddingCount);
  // process 3 bytes at a time, churning out 4 output bytes
  // worry about CRLF insertions later
  for (int i = 0; i < string.length(); i += 3) {
   int j = (string.charAt(i) << 16) + (string.charAt( i + 1) << 8 ) +
    string.charAt( i + 2);
   encoded = encoded + base64code.charAt((j >> 18 ) & 0x3f) +
    base64code.charAt((j >> 12) & 0x3f) +
    base64code.charAt((j >> 6) & 0x3f) +
    base64code.charAt(j & 0x3f);
  }
  // replace encoded padding nulls with "="
  return splitLines(encoded.substring(0, encoded.length() - paddingCount) +
   "==".substring(0, paddingCount));
 }
 public static String splitLines(String string) {
  String lines = "";
  for (int i = 0; i < string.length(); i += splitLinesAt) {
   lines += string.substring(i, Math.min(string.length(), i + splitLinesAt));
   lines += "\r\n";
  }
  return lines;
 }
 public static void main(String&#91;&#93; args) {
  for (int i = 0; i < args.length; i++) {
   System.err.println("encoding \"" + args&#91;i&#93; + "\"");
   System.out.println(base64Encode(args&#91;i&#93;));
  }
 }
}

&#91;/sourcecode&#93;

Base 64 encoding and decoding utility using xerces api

&#91;sourcecode="java"&#93;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.apache.xerces.impl.dv.util.Base64;

public class Base64Utility {

 public static String encodeObject(Object object) throws IOException {
 String result = null;
 ByteArrayOutputStream ostream = new ByteArrayOutputStream();
 ObjectOutputStream os = null;
 os = new ObjectOutputStream(ostream);
 os.writeObject(object);
 byte&#91;&#93; datatoEncode = ostream.toByteArray();
 result = Base64.encode(datatoEncode);
 os.close();
 ostream.close();
 return result;
 }

 public static Object decodeObject(String data) throws IOException, ClassNotFoundException {
 byte&#91;&#93; content = Base64.decode(data);
 ObjectInputStream oistream = new ObjectInputStream(new ByteArrayInputStream(content));
 Object obj = oistream.readObject();
 oistream.close();
 return obj;
 }
&#91;/sourcecode&#93;and the client code

&#91;sourcecode="java"&#93;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Base64Client {
 private static String encodedStringMap;

 @SuppressWarnings("unchecked" )
 public static void main(String&#91;&#93; args) throws IOException, ClassNotFoundException {
 Map<String, String> map = new HashMap<String, String> ();
 map.put("Vikas", "Hazrati");

 encodedStringMap = Base64Utility.encodeObject(map);
 System.out.println(encodedStringMap);

 Map<String, String> decodedMap;
 decodedMap = ( Map<String, String> ) Base64Utility.decodeObject(encodedStringMap);
 System.out.println(decodedMap.get("Vikas"));

 }
}
Posted in: Java