dcsimg
September 19, 2020
Hot Topics:

Java Applet for Signing with a Smart Card

  • By Svetlin Nakov
  • Send Email »
  • More Articles »

Listing 3: Base64Utils.java

/**
 * Provides utilities for Base64 encode/decode of binary data.
 */

public class Base64Utils {

   private static byte[] mBase64EncMap, mBase64DecMap;

   /**
    * Class initializer. Initializes the Base64 alphabet
    * (specified in RFC-2045).
    */

   static {
   byte[] base64Map = {
      (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F',
      (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L',
      (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R',
      (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X',
      (byte)'Y', (byte)'Z',
      (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f',
      (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l',
      (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r',
      (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x',
      (byte)'y', (byte)'z',
      (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
      (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' };
   mBase64EncMap = base64Map;
   mBase64DecMap = new byte[128];
   for (int i=0; i<mBase64EncMap.length; i++)
      mBase64DecMap[mBase64EncMap[i]] = (byte) i;
   }

   /**
    * This class isn't meant to be instantiated.
    */

   private Base64Utils() {
   }

   /**
    * Encodes the given byte[] using the Base64-encoding,
    * as specified in RFC-2045 (Section 6.8).
    *
    * @param aData the data to be encoded
    * @return the Base64-encoded <var>aData</var>
    * @exception IllegalArgumentException if NULL or empty
    * array is passed
    */

   public static String base64Encode(byte[] aData) {
   if ((aData == null) || (aData.length == 0))
      throw new IllegalArgumentException(
         "Cannot encode NULL or empty byte array.");

   byte encodedBuf[] = new byte[((aData.length+2)/3)*4];

   // 3-byte to 4-byte conversion
   int srcIndex, destIndex;
   for (srcIndex=0, destIndex=0; srcIndex < aData.length-2;
        srcIndex += 3) {
      encodedBuf[destIndex++] = 
         mBase64EncMap[(aData[srcIndex] >>> 2) & 077];
      encodedBuf[destIndex++] = mBase64EncMap[
         (aData[srcIndex+1] >>> 4) & 017 |
         (aData[srcIndex] << 4) & 077];
      encodedBuf[destIndex++] = mBase64EncMap[
         (aData[srcIndex+2] >>> 6) & 003 |
         (aData[srcIndex+1] << 2) & 077];
      encodedBuf[destIndex++] = mBase64EncMap[
         aData[srcIndex+2] & 077];
   }

   // Convert the last 1 or 2 bytes
   if (srcIndex < aData.length) {
      encodedBuf[destIndex++] = 
         mBase64EncMap[(aData[srcIndex] >>> 2) & 077];
      if (srcIndex < aData.length-1) {
         encodedBuf[destIndex++] =
            mBase64EncMap[(aData[srcIndex+1] >>> 4) & 017 |
               (aData[srcIndex] << 4) & 077];
      encodedBuf[destIndex++] = 
         mBase64EncMap[(aData[srcIndex+1] << 2) & 077];
   }
   else {
      encodedBuf[destIndex++] = 
         mBase64EncMap[(aData[srcIndex] << 4) & 077];
      }
   }

   // Add padding to the end of encoded data
   while (destIndex < encodedBuf.length) {
      encodedBuf[destIndex] = (byte) '=';
      destIndex++;
   }

   String result = new String(encodedBuf);
   return result;
   }


   /**
    * Decodes the given Base64-encoded data,
    * as specified in RFC-2045 (Section 6.8).
    *
    * @param aData the Base64-encoded aData.
    * @return the decoded <var>aData</var>.
    * @exception IllegalArgumentException if NULL or empty data
    * is passed
    */

   public static byte[] base64Decode(String aData) {
   if ((aData == null) || (aData.length() == 0))
      throw new IllegalArgumentException(
         "Cannot decode NULL or empty string.");

   byte[] data = aData.getBytes();

   // Skip padding from the end of encoded data
   int tail = data.length;
   while (data[tail-1] == '=')
      tail--;

   byte decodedBuf[] = new byte[tail - data.length/4];

   // ASCII-printable to 0-63 conversion
   for (int i = 0; i < data.length; i++)
      data[i] = mBase64DecMap[data[i]];

   // 4-byte to 3-byte conversion
   int srcIndex, destIndex;
   for (srcIndex = 0, destIndex=0; destIndex < decodedBuf.length-2;
         srcIndex += 4, destIndex += 3) {
      decodedBuf[destIndex] = (byte) 
         ( ((data[srcIndex] << 2) & 255) |
         ((data[srcIndex+1] >>> 4) & 003) );
      decodedBuf[destIndex+1] = (byte)
         ( ((data[srcIndex+1] << 4) & 255) |
         ((data[srcIndex+2] >>> 2) & 017) );
      decodedBuf[destIndex+2] = (byte)
         ( ((data[srcIndex+2] << 6) & 255) |
         (data[srcIndex+3] & 077) );
   }

   // Handle last 1 or 2 bytes
   if (destIndex < decodedBuf.length)
      decodedBuf[destIndex] = (byte) ( 
         ((data[srcIndex] << 2) & 255) |
         ((data[srcIndex+1] >>> 4) & 003) );
   if (++destIndex < decodedBuf.length)
      decodedBuf[destIndex] = (byte) 
         ( ((data[srcIndex+1] << 4) & 255) |
         ((data[srcIndex+2] >>> 2) & 017) );

   return decodedBuf;
   }

}




Page 7 of 8



This article was originally published on February 24, 2006

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.


Thanks for your registration, follow us on our social networks to keep up-to-date