src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java

Print this page

        

@@ -1,24 +1,26 @@
 /*
  * reserved comment block
  * DO NOT REMOVE OR ALTER!
  */
-/*
- * Copyright  1999-2004 The Apache Software Foundation.
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 package com.sun.org.apache.xml.internal.security.utils;
 
 import java.io.BufferedReader;
 import java.io.IOException;

@@ -30,38 +32,80 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.Text;
 
-
 /**
  * Implementation of MIME's Base64 encoding and decoding conversions.
  * Optimized code. (raw version taken from oreilly.jonathan.util,
- * and currently com.sun.org.apache.xerces.internal.ds.util.Base64)
+ * and currently org.apache.xerces.ds.util.Base64)
  *
  * @author Raul Benito(Of the xerces copy, and little adaptations).
  * @author Anli Shundi
  * @author Christian Geuer-Pollmann
- * @see <A HREF="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</A>
+ * @see <A HREF="ftp://ftp.isi.edu/in-notes/rfc2045.txt">RFC 2045</A>
  * @see com.sun.org.apache.xml.internal.security.transforms.implementations.TransformBase64Decode
  */
 public class Base64 {
 
-
    /** Field BASE64DEFAULTLENGTH */
    public static final int BASE64DEFAULTLENGTH = 76;
 
+    private static final int BASELENGTH = 255;
+    private static final int LOOKUPLENGTH = 64;
+    private static final int TWENTYFOURBITGROUP = 24;
+    private static final int EIGHTBIT = 8;
+    private static final int SIXTEENBIT = 16;
+    private static final int FOURBYTE = 4;
+    private static final int SIGN = -128;
+    private static final char PAD = '=';   
+    private static final byte [] base64Alphabet = new byte[BASELENGTH];
+    private static final char [] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+    static {
+        for (int i = 0; i < BASELENGTH; i++) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i - 'A');
+        }
+        for (int i = 'z'; i>= 'a'; i--) {
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        }
+
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i - '0' + 52);
+        }
+
+        base64Alphabet['+'] = 62;
+        base64Alphabet['/'] = 63;
+
+        for (int i = 0; i <= 25; i++) {
+            lookUpBase64Alphabet[i] = (char)('A' + i);
+        }
+
+        for (int i = 26,  j = 0; i <= 51; i++, j++) {
+            lookUpBase64Alphabet[i] = (char)('a' + j);
+        }
+
+        for (int i = 52,  j = 0; i <= 61; i++, j++) {
+            lookUpBase64Alphabet[i] = (char)('0' + j);
+        }
+        lookUpBase64Alphabet[62] = '+';
+        lookUpBase64Alphabet[63] = '/';
+    }
+
    private Base64() {
      // we don't allow instantiation
    }
 
    /**
     * Returns a byte-array representation of a <code>{@link BigInteger}<code>.
-    * No sign-bit is outputed.
+     * No sign-bit is output.
     *
     * <b>N.B.:</B> <code>{@link BigInteger}<code>'s toByteArray
-    * retunrs eventually longer arrays because of the leading sign-bit.
+     * returns eventually longer arrays because of the leading sign-bit.
     *
     * @param big <code>BigInteger<code> to be converted
     * @param bitlen <code>int<code> the desired length in bits of the representation
     * @return a byte array with <code>bitlen</code> bits of <code>big</code>
     */

@@ -69,12 +113,11 @@
 
       //round bitlen
       bitlen = ((bitlen + 7) >> 3) << 3;
 
       if (bitlen < big.bitLength()) {
-         throw new IllegalArgumentException(I18n
-            .translate("utils.Base64.IllegalBitlength"));
+            throw new IllegalArgumentException(I18n.translate("utils.Base64.IllegalBitlength"));
       }
 
       byte[] bigBytes = big.toByteArray();
 
       if (((big.bitLength() % 8) != 0)

@@ -96,11 +139,10 @@
          byte[] resizedBytes = new byte[bitlen / 8];
 
          System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, bigLen);
 
          return resizedBytes;
-
    }
 
    /**
     * Encode in Base64 the given <code>{@link BigInteger}<code>.
     *

@@ -111,14 +153,14 @@
       return encode(getBytes(big, big.bitLength()));
    }
 
    /**
     * Returns a byte-array representation of a <code>{@link BigInteger}<code>.
-    * No sign-bit is outputed.
+     * No sign-bit is output.
     *
     * <b>N.B.:</B> <code>{@link BigInteger}<code>'s toByteArray
-    * retunrs eventually longer arrays because of the leading sign-bit.
+     * returns eventually longer arrays because of the leading sign-bit.
     *
     * @param big <code>BigInteger<code> to be converted
     * @param bitlen <code>int<code> the desired length in bits of the representation
     * @return a byte array with <code>bitlen</code> bits of <code>big</code>
     */

@@ -126,12 +168,11 @@
 
       //round bitlen
       bitlen = ((bitlen + 7) >> 3) << 3;
 
       if (bitlen < big.bitLength()) {
-         throw new IllegalArgumentException(I18n
-            .translate("utils.Base64.IllegalBitlength"));
+            throw new IllegalArgumentException(I18n.translate("utils.Base64.IllegalBitlength"));
       }
 
       byte[] bigBytes = big.toByteArray();
 
       if (((big.bitLength() % 8) != 0)

@@ -153,50 +194,48 @@
          byte[] resizedBytes = new byte[bitlen / 8];
 
          System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, bigLen);
 
          return resizedBytes;
-
    }
 
    /**
     * Method decodeBigIntegerFromElement
     *
     * @param element
-    * @return the biginter obtained from the node
+     * @return the biginteger obtained from the node
     * @throws Base64DecodingException
     */
-   public static final BigInteger decodeBigIntegerFromElement(Element element) throws Base64DecodingException
-   {
+    public static final BigInteger decodeBigIntegerFromElement(Element element) 
+        throws Base64DecodingException {
       return new BigInteger(1, Base64.decode(element));
    }
 
    /**
     * Method decodeBigIntegerFromText
     *
     * @param text
     * @return the biginter obtained from the text node
     * @throws Base64DecodingException
     */
-   public static final BigInteger decodeBigIntegerFromText(Text text) throws Base64DecodingException
-   {
+    public static final BigInteger decodeBigIntegerFromText(Text text) 
+        throws Base64DecodingException {
       return new BigInteger(1, Base64.decode(text.getData()));
    }
 
    /**
     * This method takes an (empty) Element and a BigInteger and adds the
     * base64 encoded BigInteger to the Element.
     *
     * @param element
     * @param biginteger
     */
-   public static final void fillElementWithBigInteger(Element element,
-           BigInteger biginteger) {
+    public static final void fillElementWithBigInteger(Element element, BigInteger biginteger) {
 
       String encodedInt = encode(biginteger);
 
-      if (encodedInt.length() > 76) {
+        if (!XMLUtils.ignoreLineBreaks() && encodedInt.length() > BASE64DEFAULTLENGTH) {
          encodedInt = "\n" + encodedInt + "\n";
       }
 
       Document doc = element.getOwnerDocument();
       Text text = doc.createTextNode(encodedInt);

@@ -218,17 +257,17 @@
    public static final byte[] decode(Element element) throws Base64DecodingException {
 
       Node sibling = element.getFirstChild();
       StringBuffer sb = new StringBuffer();
 
-      while (sibling!=null) {
+        while (sibling != null) {
          if (sibling.getNodeType() == Node.TEXT_NODE) {
             Text t = (Text) sibling;
 
             sb.append(t.getData());
          }
-         sibling=sibling.getNextSibling();
+            sibling = sibling.getNextSibling();
       }
 
       return decode(sb.toString());
    }
 

@@ -239,13 +278,11 @@
     * @param localName
     * @param bytes
     * @return an Element with the base64 encoded in the text.
     *
     */
-   public static final Element encodeToElement(Document doc, String localName,
-                                         byte[] bytes) {
-
+    public static final Element encodeToElement(Document doc, String localName, byte[] bytes) {
       Element el = XMLUtils.createElementInSignatureSpace(doc, localName);
       Text text = doc.createTextNode(encode(bytes));
 
       el.appendChild(text);
 

@@ -253,22 +290,19 @@
    }
 
    /**
     * Method decode
     *
-    *
     * @param base64
     * @return the UTF bytes of the base64
     * @throws Base64DecodingException
     *
     */
-   public final static byte[] decode(byte[] base64) throws Base64DecodingException  {
+    public static final byte[] decode(byte[] base64) throws Base64DecodingException  {             
          return decodeInternal(base64, -1);
    }
 
-
-
    /**
     * Encode a byte array and fold lines at the standard 76th character unless
     * ignore line breaks property is set.
     *
     * @param binaryData <code>byte[]<code> to be base64 encoded

@@ -282,86 +316,47 @@
 
    /**
     * Base64 decode the lines from the reader and return an InputStream
     * with the bytes.
     *
-    *
     * @param reader
     * @return InputStream with the decoded bytes
     * @exception IOException passes what the reader throws
     * @throws IOException
     * @throws Base64DecodingException
     */
-   public final static byte[] decode(BufferedReader reader)
+    public static final byte[] decode(BufferedReader reader)
            throws IOException, Base64DecodingException {
 
-      UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream();
+        byte[] retBytes = null;
+        UnsyncByteArrayOutputStream baos = null;
+        try {
+            baos = new UnsyncByteArrayOutputStream();
       String line;
 
       while (null != (line = reader.readLine())) {
          byte[] bytes = decode(line);
-
          baos.write(bytes);
       }
-
-      return baos.toByteArray();
-   }
-
-   static private final int  BASELENGTH         = 255;
-   static private final int  LOOKUPLENGTH       = 64;
-   static private final int  TWENTYFOURBITGROUP = 24;
-   static private final int  EIGHTBIT           = 8;
-   static private final int  SIXTEENBIT         = 16;
-   static private final int  FOURBYTE           = 4;
-   static private final int  SIGN               = -128;
-   static private final char PAD                = '=';
-   static final private byte [] base64Alphabet        = new byte[BASELENGTH];
-   static final private char [] lookUpBase64Alphabet  = new char[LOOKUPLENGTH];
-
-   static {
-
-       for (int i = 0; i<BASELENGTH; i++) {
-           base64Alphabet[i] = -1;
-       }
-       for (int i = 'Z'; i >= 'A'; i--) {
-           base64Alphabet[i] = (byte) (i-'A');
-       }
-       for (int i = 'z'; i>= 'a'; i--) {
-           base64Alphabet[i] = (byte) ( i-'a' + 26);
+            retBytes = baos.toByteArray();
+        } finally {
+            baos.close();
        }
 
-       for (int i = '9'; i >= '0'; i--) {
-           base64Alphabet[i] = (byte) (i-'0' + 52);
-       }
-
-       base64Alphabet['+']  = 62;
-       base64Alphabet['/']  = 63;
-
-       for (int i = 0; i<=25; i++)
-           lookUpBase64Alphabet[i] = (char)('A'+i);
-
-       for (int i = 26,  j = 0; i<=51; i++, j++)
-           lookUpBase64Alphabet[i] = (char)('a'+ j);
-
-       for (int i = 52,  j = 0; i<=61; i++, j++)
-           lookUpBase64Alphabet[i] = (char)('0' + j);
-       lookUpBase64Alphabet[62] = '+';
-       lookUpBase64Alphabet[63] = '/';
-
+        return retBytes;
    }
 
    protected static final boolean isWhiteSpace(byte octect) {
        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
    }
 
    protected static final boolean isPad(byte octect) {
        return (octect == PAD);
    }
 
-
    /**
-    * Encodes hex octects into Base64
+     * Encodes hex octets into Base64
     *
     * @param binaryData Array containing binaryData
     * @return Encoded Base64 array
     */
    /**

@@ -371,423 +366,433 @@
     * @param binaryData <code>byte[]</code> data to be encoded
     * @param length <code>int<code> length of wrapped lines; No wrapping if less than 4.
     * @return a <code>String</code> with encoded data
     */
     public static final String  encode(byte[] binaryData,int length) {
-
-        if (length<4) {
-                length=Integer.MAX_VALUE;
+        if (length < 4) {
+            length = Integer.MAX_VALUE;
         }
 
-       if (binaryData == null)
+        if (binaryData == null) {
            return null;
+        }
 
-       int      lengthDataBits    = binaryData.length*EIGHTBIT;
+        int lengthDataBits = binaryData.length * EIGHTBIT;
        if (lengthDataBits == 0) {
            return "";
        }
 
-       int      fewerThan24bits   = lengthDataBits%TWENTYFOURBITGROUP;
-       int      numberTriplets    = lengthDataBits/TWENTYFOURBITGROUP;
-       int      numberQuartet     = fewerThan24bits != 0 ? numberTriplets+1 : numberTriplets;
-       int      quartesPerLine    = length/4;
-       int      numberLines       = (numberQuartet-1)/quartesPerLine;
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
+        int quartesPerLine = length / 4;
+        int numberLines = (numberQuartet - 1) / quartesPerLine;
        char     encodedData[]     = null;
 
-       encodedData = new char[numberQuartet*4+numberLines];
-
-       byte k=0, l=0, b1=0,b2=0,b3=0;
+        encodedData = new char[numberQuartet * 4 + numberLines];
 
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
        int encodedIndex = 0;
        int dataIndex   = 0;
        int i           = 0;
 
-
        for (int line = 0; line < numberLines; line++) {
            for (int quartet = 0; quartet < 19; quartet++) {
                b1 = binaryData[dataIndex++];
                b2 = binaryData[dataIndex++];
                b3 = binaryData[dataIndex++];
 
-
                l  = (byte)(b2 & 0x0f);
                k  = (byte)(b1 & 0x03);
 
-               byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
+                byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2): (byte)((b1) >> 2 ^ 0xc0);
 
-               byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
-               byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc);
+                byte val2 = ((b2 & SIGN) == 0) ? (byte)(b2 >> 4) : (byte)((b2) >> 4 ^ 0xf0);
+                byte val3 = ((b3 & SIGN) == 0) ? (byte)(b3 >> 6) : (byte)((b3) >> 6 ^ 0xfc);
 
 
-               encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
-               encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
-               encodedData[encodedIndex++] = lookUpBase64Alphabet[ (l <<2 ) | val3 ];
-               encodedData[encodedIndex++] = lookUpBase64Alphabet[ b3 & 0x3f ];
+                encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+                encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+                encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+                encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
 
                i++;
            }
                 encodedData[encodedIndex++] = 0xa;
        }
 
-       for (; i<numberTriplets; i++) {
+        for (; i < numberTriplets; i++) {
            b1 = binaryData[dataIndex++];
            b2 = binaryData[dataIndex++];
            b3 = binaryData[dataIndex++];
 
-
            l  = (byte)(b2 & 0x0f);
            k  = (byte)(b1 & 0x03);
 
-           byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
+            byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2) : (byte)((b1) >> 2 ^ 0xc0);
 
-           byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
-           byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte)(b2 >> 4) : (byte)((b2) >> 4 ^ 0xf0);
+            byte val3 = ((b3 & SIGN) == 0) ? (byte)(b3 >> 6) : (byte)((b3) >> 6 ^ 0xfc);
 
 
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ (l <<2 ) | val3 ];
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ b3 & 0x3f ];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
        }
 
        // form integral number of 6-bit groups
        if (fewerThan24bits == EIGHTBIT) {
            b1 = binaryData[dataIndex];
-           k = (byte) ( b1 &0x03 );
-          byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ k<<4 ];
+            k = (byte) (b1 &0x03);
+            byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2):(byte)((b1) >> 2 ^ 0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
            encodedData[encodedIndex++] = PAD;
            encodedData[encodedIndex++] = PAD;
        } else if (fewerThan24bits == SIXTEENBIT) {
            b1 = binaryData[dataIndex];
            b2 = binaryData[dataIndex +1 ];
-           l = ( byte ) ( b2 &0x0f );
-           k = ( byte ) ( b1 &0x03 );
+            l = ( byte ) (b2 & 0x0f);
+            k = ( byte ) (b1 & 0x03);
 
-           byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
-           byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
+            byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2) : (byte)((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte)(b2 >> 4) : (byte)((b2) >> 4 ^ 0xf0);
 
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
-           encodedData[encodedIndex++] = lookUpBase64Alphabet[ l<<2 ];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
            encodedData[encodedIndex++] = PAD;
        }
 
        //encodedData[encodedIndex] = 0xa;
 
        return new String(encodedData);
    }
 
     /**
-     * Decodes Base64 data into octects
+     * Decodes Base64 data into octets
      *
      * @param encoded String containing base64 encoded data
      * @return byte array containing the decoded data
      * @throws Base64DecodingException if there is a problem decoding the data
      */
-    public final static byte[] decode(String encoded) throws Base64DecodingException {
-
-        if (encoded == null)
+    public static final byte[] decode(String encoded) throws Base64DecodingException {
+        if (encoded == null) {
                 return null;
-        byte []bytes=new byte[encoded.length()];
-        int len=getBytesInternal(encoded, bytes);
+        }
+        byte[] bytes = new byte[encoded.length()];
+        int len = getBytesInternal(encoded, bytes);
         return decodeInternal(bytes, len);
         }
 
-    protected static final int getBytesInternal(String s,byte[] result) {
-        int length=s.length();
+    protected static final int getBytesInternal(String s, byte[] result) {
+        int length = s.length();
 
-        int newSize=0;
+        int newSize = 0;
         for (int i = 0; i < length; i++) {
-            byte dataS=(byte)s.charAt(i);
-            if (!isWhiteSpace(dataS))
+            byte dataS = (byte)s.charAt(i);
+            if (!isWhiteSpace(dataS)) {
                 result[newSize++] = dataS;
         }
+        }
         return newSize;
-
     }
-   protected final static byte[] decodeInternal(byte[] base64Data, int len) throws Base64DecodingException {
+
+    protected static final byte[] decodeInternal(byte[] base64Data, int len) 
+        throws Base64DecodingException {
        // remove white spaces
-           if (len==-1)
+        if (len == -1) {
           len = removeWhiteSpace(base64Data);
+        }
 
-       if (len%FOURBYTE != 0) {
+        if (len % FOURBYTE != 0) {
            throw new Base64DecodingException("decoding.divisible.four");
            //should be divisible by four
        }
 
-       int      numberQuadruple    = (len/FOURBYTE );
+        int numberQuadruple = (len / FOURBYTE);
 
-       if (numberQuadruple == 0)
+        if (numberQuadruple == 0) {
            return new byte[0];
+        }
 
        byte     decodedData[]      = null;
-       byte     b1=0,b2=0,b3=0, b4=0;
-
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
 
        int i = 0;
        int encodedIndex = 0;
        int dataIndex    = 0;
 
        //decodedData      = new byte[ (numberQuadruple)*3];
-       dataIndex=(numberQuadruple-1)*4;
-       encodedIndex=(numberQuadruple-1)*3;
+        dataIndex = (numberQuadruple - 1) * 4;
+        encodedIndex = (numberQuadruple - 1) * 3;
        //first last bits.
        b1 = base64Alphabet[base64Data[dataIndex++]];
        b2 = base64Alphabet[base64Data[dataIndex++]];
        if ((b1==-1) || (b2==-1)) {
-                throw new Base64DecodingException("decoding.general");//if found "no data" just return null
+             //if found "no data" just return null
+            throw new Base64DecodingException("decoding.general");
         }
 
 
-        byte d3,d4;
-        b3 = base64Alphabet[d3=base64Data[dataIndex++]];
-        b4 = base64Alphabet[d4=base64Data[dataIndex++]];
-        if ((b3==-1 ) || (b4==-1) ) {
+        byte d3, d4;
+        b3 = base64Alphabet[d3 = base64Data[dataIndex++]];
+        b4 = base64Alphabet[d4 = base64Data[dataIndex++]];
+        if ((b3 == -1) || (b4 == -1) ) {
                 //Check if they are PAD characters
-            if (isPad( d3 ) && isPad( d4)) {               //Two PAD e.g. 3c[Pad][Pad]
-                if ((b2 & 0xf) != 0)//last 4 bits should be zero
+            if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
+                if ((b2 & 0xf) != 0) { //last 4 bits should be zero
+                    throw new Base64DecodingException("decoding.general");
+                }
+                decodedData = new byte[encodedIndex + 1];                
+                decodedData[encodedIndex]   = (byte)(b1 << 2 | b2 >> 4) ;                
+            } else if (!isPad(d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]                
+                if ((b3 & 0x3) != 0) { //last 2 bits should be zero
                         throw new Base64DecodingException("decoding.general");
-                decodedData = new byte[ encodedIndex + 1 ];
-                decodedData[encodedIndex]   = (byte)(  b1 <<2 | b2>>4 ) ;
-            } else if (!isPad( d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
-                if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
-                        throw new Base64DecodingException("decoding.general");
-                decodedData = new byte[ encodedIndex + 2 ];
-                decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 );
-                decodedData[encodedIndex]   = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
+                }
+                decodedData = new byte[encodedIndex + 2];                
+                decodedData[encodedIndex++] = (byte)(b1 << 2 | b2 >> 4);
+                decodedData[encodedIndex] = (byte)(((b2 & 0xf) << 4) |((b3 >> 2) & 0xf));                
             } else {
-                throw new Base64DecodingException("decoding.general");//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
+                //an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
+                throw new Base64DecodingException("decoding.general");
             }
         } else {
             //No PAD e.g 3cQl
             decodedData = new byte[encodedIndex+3];
-            decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 ) ;
-            decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
-            decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
+            decodedData[encodedIndex++] = (byte)(b1 << 2 | b2 >> 4) ;
+            decodedData[encodedIndex++] = (byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte)(b3 << 6 | b4);
         }
-        encodedIndex=0;
-        dataIndex=0;
+        encodedIndex = 0;
+        dataIndex = 0;
        //the begin
-       for (i=numberQuadruple-1; i>0; i--) {
+        for (i = numberQuadruple - 1; i > 0; i--) {
            b1 = base64Alphabet[base64Data[dataIndex++]];
            b2 = base64Alphabet[base64Data[dataIndex++]];
            b3 = base64Alphabet[base64Data[dataIndex++]];
            b4 = base64Alphabet[base64Data[dataIndex++]];
 
-           if ( (b1==-1) ||
-                        (b2==-1) ||
-                        (b3==-1) ||
-                        (b4==-1) ) {
-                   throw new Base64DecodingException("decoding.general");//if found "no data" just return null
+            if ((b1 == -1) ||
+                (b2 == -1) ||
+                (b3 == -1) ||
+                (b4 == -1)) {
+                //if found "no data" just return null   
+                throw new Base64DecodingException("decoding.general");
            }
 
-           decodedData[encodedIndex++] = (byte)(  b1 <<2 | b2>>4 ) ;
-           decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
-           decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
+            decodedData[encodedIndex++] = (byte)(b1 << 2 | b2 >> 4) ;
+            decodedData[encodedIndex++] = (byte)(((b2 & 0xf) << 4) |((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte)(b3 << 6 | b4 );
        }
        return decodedData;
    }
+
    /**
     * Decodes Base64 data into  outputstream
     *
     * @param base64Data String containing Base64 data
     * @param os the outputstream
     * @throws IOException
     * @throws Base64DecodingException
     */
-   public final static void decode(String base64Data,
-        OutputStream os) throws Base64DecodingException, IOException {
-           byte[] bytes=new byte[base64Data.length()];
-           int len=getBytesInternal(base64Data, bytes);
+    public static final void decode(String base64Data, OutputStream os) 
+        throws Base64DecodingException, IOException {
+        byte[] bytes = new byte[base64Data.length()];
+        int len = getBytesInternal(base64Data, bytes);
            decode(bytes,os,len);
    }
+
    /**
     * Decodes Base64 data into  outputstream
     *
     * @param base64Data Byte array containing Base64 data
     * @param os the outputstream
     * @throws IOException
     * @throws Base64DecodingException
     */
-   public final static void decode(byte[] base64Data,
-        OutputStream os) throws Base64DecodingException, IOException {
+    public static final void decode(byte[] base64Data, OutputStream os) 
+        throws Base64DecodingException, IOException {       
             decode(base64Data,os,-1);
    }
-   protected final static void decode(byte[] base64Data,
-                        OutputStream os,int len) throws Base64DecodingException, IOException {
 
+    protected static final void decode(byte[] base64Data, OutputStream os, int len) 
+        throws Base64DecodingException, IOException {       
         // remove white spaces
-    if (len==-1)
+        if (len == -1) {
        len = removeWhiteSpace(base64Data);
+        }
 
-    if (len%FOURBYTE != 0) {
+        if (len % FOURBYTE != 0) {
         throw new Base64DecodingException("decoding.divisible.four");
         //should be divisible by four
     }
 
-    int      numberQuadruple    = (len/FOURBYTE );
+        int numberQuadruple = (len / FOURBYTE);
 
-    if (numberQuadruple == 0)
+        if (numberQuadruple == 0) {
         return;
+        }
 
     //byte     decodedData[]      = null;
-    byte     b1=0,b2=0,b3=0, b4=0;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
 
     int i = 0;
-
     int dataIndex    = 0;
 
     //the begin
-    for (i=numberQuadruple-1; i>0; i--) {
+        for (i=numberQuadruple - 1; i > 0; i--) {
         b1 = base64Alphabet[base64Data[dataIndex++]];
         b2 = base64Alphabet[base64Data[dataIndex++]];
         b3 = base64Alphabet[base64Data[dataIndex++]];
         b4 = base64Alphabet[base64Data[dataIndex++]];
-        if ( (b1==-1) ||
-                (b2==-1) ||
-                (b3==-1) ||
-                (b4==-1) )
-         throw new Base64DecodingException("decoding.general");//if found "no data" just return null
-
-
+            if ((b1 == -1) ||
+                (b2 == -1) ||
+                (b3 == -1) ||
+                (b4 == -1) ) {
+                //if found "no data" just return null
+                throw new Base64DecodingException("decoding.general");
+            }
 
-        os.write((byte)(  b1 <<2 | b2>>4 ) );
-        os.write((byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
-        os.write( (byte)( b3<<6 | b4 ));
+            os.write((byte)(b1 << 2 | b2 >> 4));
+            os.write((byte)(((b2 & 0xf) << 4 ) | ((b3 >> 2) & 0xf)));
+            os.write( (byte)(b3 << 6 | b4));
     }
     b1 = base64Alphabet[base64Data[dataIndex++]];
     b2 = base64Alphabet[base64Data[dataIndex++]];
 
     //  first last bits.
-    if ((b1==-1) ||
-        (b2==-1) ){
-             throw new Base64DecodingException("decoding.general");//if found "no data" just return null
-     }
-
-     byte d3,d4;
-     b3= base64Alphabet[d3 = base64Data[dataIndex++]];
-     b4= base64Alphabet[d4 = base64Data[dataIndex++]];
-     if ((b3==-1 ) ||
-          (b4==-1) ) {//Check if they are PAD characters
-         if (isPad( d3 ) && isPad( d4)) {               //Two PAD e.g. 3c[Pad][Pad]
-             if ((b2 & 0xf) != 0)//last 4 bits should be zero
-                     throw new Base64DecodingException("decoding.general");
-             os.write( (byte)(  b1 <<2 | b2>>4 ) );
-         } else if (!isPad( d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
-             if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
+        if ((b1 == -1) || (b2 == -1) ) {
+            //if found "no data" just return null
+            throw new Base64DecodingException("decoding.general");
+        }
+
+        byte d3, d4;
+        b3 = base64Alphabet[d3 = base64Data[dataIndex++]];
+        b4 = base64Alphabet[d4 = base64Data[dataIndex++]];
+        if ((b3 == -1 ) || (b4 == -1) ) { //Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
+                if ((b2 & 0xf) != 0) { //last 4 bits should be zero
                      throw new Base64DecodingException("decoding.general");
-             os.write( (byte)(  b1 <<2 | b2>>4 ));
-             os.write( (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
+                }
+                os.write((byte)(b1 << 2 | b2 >> 4));                
+            } else if (!isPad(d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]             
+                if ((b3 & 0x3 ) != 0) { //last 2 bits should be zero
+                    throw new Base64DecodingException("decoding.general");
+                }
+                os.write((byte)(b1 << 2 | b2 >> 4));
+                os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));                
          } else {
-             throw new Base64DecodingException("decoding.general");//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
+                //an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
+                throw new Base64DecodingException("decoding.general");
          }
      } else {
          //No PAD e.g 3cQl
-         os.write((byte)(  b1 <<2 | b2>>4 ) );
-         os.write( (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
-         os.write((byte)( b3<<6 | b4 ));
+            os.write((byte)(b1 << 2 | b2 >> 4));
+            os.write( (byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
+            os.write((byte)(b3 << 6 | b4));
      }
-    return ;
    }
 
    /**
     * Decodes Base64 data into  outputstream
     *
     * @param is containing Base64 data
     * @param os the outputstream
     * @throws IOException
     * @throws Base64DecodingException
     */
-   public final static void decode(InputStream is,
-        OutputStream os) throws Base64DecodingException, IOException {
+    public static final void decode(InputStream is, OutputStream os) 
+        throws Base64DecodingException, IOException {
         //byte     decodedData[]      = null;
-    byte     b1=0,b2=0,b3=0, b4=0;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;    
 
     int index=0;
-    byte []data=new byte[4];
+        byte[] data = new byte[4];
     int read;
     //the begin
-    while ((read=is.read())>0) {
-        byte readed=(byte)read;
+        while ((read = is.read()) > 0) {
+            byte readed = (byte)read;
         if (isWhiteSpace(readed)) {
                 continue;
         }
         if (isPad(readed)) {
-            data[index++]=readed;
-            if (index==3)
-                data[index++]=(byte)is.read();
+                data[index++] = readed;
+                if (index == 3) {
+                    data[index++] = (byte)is.read();
+                }
             break;
         }
 
-
-        if ((data[index++]=readed)==-1) {
-            throw new Base64DecodingException("decoding.general");//if found "no data" just return null
+            if ((data[index++] = readed) == -1) {
+                //if found "no data" just return null
+                throw new Base64DecodingException("decoding.general");
            }
 
-        if (index!=4) {
+            if (index != 4) {
                 continue;
         }
-        index=0;
+            index = 0;
         b1 = base64Alphabet[data[0]];
         b2 = base64Alphabet[data[1]];
         b3 = base64Alphabet[data[2]];
         b4 = base64Alphabet[data[3]];
 
-        os.write((byte)(  b1 <<2 | b2>>4 ) );
-        os.write((byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
-        os.write( (byte)( b3<<6 | b4 ));
+            os.write((byte)(b1 << 2 | b2 >> 4));
+            os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
+            os.write((byte)(b3 << 6 | b4));
     }
 
-
-    byte     d1=data[0],d2=data[1],d3=data[2], d4=data[3];
+        byte d1 = data[0], d2 = data[1], d3 = data[2], d4 = data[3];
     b1 = base64Alphabet[d1];
     b2 = base64Alphabet[d2];
-    b3 = base64Alphabet[ d3 ];
-    b4 = base64Alphabet[ d4 ];
-     if ((b3==-1 ) ||
-         (b4==-1) ) {//Check if they are PAD characters
-         if (isPad( d3 ) && isPad( d4)) {               //Two PAD e.g. 3c[Pad][Pad]
-             if ((b2 & 0xf) != 0)//last 4 bits should be zero
-                     throw new Base64DecodingException("decoding.general");
-             os.write( (byte)(  b1 <<2 | b2>>4 ) );
-         } else if (!isPad( d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
-             b3 = base64Alphabet[ d3 ];
-             if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
+        b3 = base64Alphabet[d3];
+        b4 = base64Alphabet[d4];
+        if ((b3 == -1) || (b4 == -1)) { //Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
+                if ((b2 & 0xf) != 0) { //last 4 bits should be zero
+                    throw new Base64DecodingException("decoding.general");
+                }
+                os.write((byte)(b1 << 2 | b2 >> 4));                
+            } else if (!isPad(d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
+                b3 = base64Alphabet[d3];
+                if ((b3 & 0x3) != 0) { //last 2 bits should be zero
                      throw new Base64DecodingException("decoding.general");
-             os.write( (byte)(  b1 <<2 | b2>>4 ));
-             os.write( (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
+                }
+                os.write((byte)(b1 << 2 | b2 >> 4));
+                os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));                
          } else {
-             throw new Base64DecodingException("decoding.general");//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
+                //an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
+                throw new Base64DecodingException("decoding.general");
          }
      } else {
          //No PAD e.g 3cQl
-
-         os.write((byte)(  b1 <<2 | b2>>4 ) );
-         os.write( (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ));
-         os.write((byte)( b3<<6 | b4 ));
+            os.write((byte)(b1 << 2 | b2 >> 4));
+            os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
+            os.write((byte)(b3 << 6 | b4));
      }
-
-    return ;
    }
+
    /**
     * remove WhiteSpace from MIME containing encoded Base64 data.
     *
     * @param data  the byte array of base64 data (with WS)
     * @return      the new length
     */
    protected static final int removeWhiteSpace(byte[] data) {
-       if (data == null)
+        if (data == null) {
            return 0;
+        }
 
        // count characters that's not whitespace
        int newSize = 0;
        int len = data.length;
        for (int i = 0; i < len; i++) {
-           byte dataS=data[i];
-           if (!isWhiteSpace(dataS))
+            byte dataS = data[i];
+            if (!isWhiteSpace(dataS)) {
                data[newSize++] = dataS;
        }
+        }
        return newSize;
    }
 }