Android Open Source - javocsoft-toolbox Base64






From Project

Back to project page javocsoft-toolbox.

License

The source code is released under:

GNU General Public License

If you think the Android project javocsoft-toolbox listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package es.javocsoft.android.lib.toolbox.encoding;
/* ww  w. j ava2  s. c o  m*/
/*
 * Copyright (C) 2001-2007 Stephen Ostermiller
 * http://ostermiller.org/contact.pl?regarding=Java+Utilities
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * See COPYING.TXT for details.
 */

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;

/**
 * Implements Base64 encoding and decoding as defined by RFC 2045:
 * "Multi-purpose Internet Mail Extensions (MIME) Part One: Format of Internet
 * Message Bodies" page 23. More information about this class is available from
 * <a target="_top" href=
 * "http://ostermiller.org/utils/Base64.html">ostermiller.org</a>.
 * 
 * <blockquote>
 * <p>
 * The Base64 Content-Transfer-Encoding is designed to represent arbitrary
 * sequences of octets in a form that need not be humanly readable. The encoding
 * and decoding algorithms are simple, but the encoded data are consistently
 * only about 33 percent larger than the unencoded data. This encoding is
 * virtually identical to the one used in Privacy Enhanced Mail (PEM)
 * applications, as defined in RFC 1421.
 * </p>
 * 
 * <p>
 * A 65-character subset of US-ASCII is used, enabling 6 bits to be represented
 * per printable character. (The extra 65th character, "=", is used to signify a
 * special processing function.)
 * </p>
 * 
 * <p>
 * NOTE: This subset has the important property that it is represented
 * identically in all versions of ISO 646, including US-ASCII, and all
 * characters in the subset are also represented identically in all versions of
 * EBCDIC. Other popular encodings, such as the encoding used by the uuencode
 * utility, MacIntosh binhex 4.0 [RFC-1741], and the base85 encoding specified
 * as part of Level 2 PostScript, do no share these properties, and thus do not
 * fulfill the portability requirements a binary transport encoding for mail
 * must meet.
 * </p>
 * 
 * <p>
 * The encoding process represents 24-bit groups of input bits as output strings
 * of 4 encoded characters. Proceeding from left to right, a 24-bit input group
 * is formed by concatenating 3 8bit input groups. These 24 bits are then
 * treated as 4 concatenated 6-bit groups, each of which is translated into a
 * single digit in the base64 alphabet. When encoding a bit stream via the
 * base64 encoding, the bit stream must be presumed to be ordered with the
 * most-significant-bit first. That is, the first bit in the stream will be the
 * high-order bit in the first 8bit byte, and the eighth bit will be the
 * low-order bit in the first 8bit byte, and so on.
 * </p>
 * 
 * <p>
 * Each 6-bit group is used as an index into an array of 64 printable
 * characters. The character referenced by the index is placed in the output
 * string. These characters, identified in Table 1, below, are selected so as to
 * be universally representable, and the set excludes characters with particular
 * significance to SMTP (e.g., ".", CR, LF) and to the multi-part boundary
 * delimiters defined in RFC 2046 (e.g., "-").
 * </p>
 * 
 * <pre>
 *                  Table 1: The Base64 Alphabet
 * 
 *   Value Encoding  Value Encoding  Value Encoding  Value Encoding
 *       0 A            17 R            34 i            51 z
 *       1 B            18 S            35 j            52 0
 *       2 C            19 T            36 k            53 1
 *       3 D            20 U            37 l            54 2
 *       4 E            21 V            38 m            55 3
 *       5 F            22 W            39 n            56 4
 *       6 G            23 X            40 o            57 5
 *       7 H            24 Y            41 p            58 6
 *       8 I            25 Z            42 q            59 7
 *       9 J            26 a            43 r            60 8
 *      10 K            27 b            44 s            61 9
 *      11 L            28 c            45 t            62 +
 *      12 M            29 d            46 u            63 /
 *      13 N            30 e            47 v
 *      14 O            31 f            48 w         (pad) =
 *      15 P            32 g            49 x
 *      16 Q            33 h            50 y
 * </pre>
 * <p>
 * The encoded output stream must be represented in lines of no more than 76
 * characters each. All line breaks or other characters no found in Table 1 must
 * be ignored by decoding software. In base64 data, characters other than those
 * in Table 1, line breaks, and other white space probably indicate a
 * transmission error, about which a warning message or even a message rejection
 * might be appropriate under some circumstances.
 * </p>
 * 
 * <p>
 * Special processing is performed if fewer than 24 bits are available at the
 * end of the data being encoded. A full encoding quantum is always completed at
 * the end of a body. When fewer than 24 input bits are available in an input
 * group, zero bits are added (on the right) to form an integral number of 6-bit
 * groups. Padding at the end of the data is performed using the "=" character.
 * Since all base64 input is an integral number of octets, only the following
 * cases can arise: (1) the final quantum of encoding input is an integral
 * multiple of 24 bits; here, the final unit of encoded output will be an
 * integral multiple of 4 characters with no "=" padding, (2) the final quantum
 * of encoding input is exactly 8 bits; here, the final unit of encoded output
 * will be two characters followed by two "=" padding characters, or (3) the
 * final quantum of encoding input is exactly 16 bits; here, the final unit of
 * encoded output will be three characters followed by one "=" padding
 * character.
 * </p>
 * 
 * <p>
 * Because it is used only for padding at the end of the data, the occurrence of
 * any "=" characters may be taken as evidence that the end of the data has been
 * reached (without truncation in transit). No such assurance is possible,
 * however, when the number of octets transmitted was a multiple of three and no
 * "=" characters are present.
 * </p>
 * 
 * <p>
 * Any characters outside of the base64 alphabet are to be ignored in
 * base64-encoded data.
 * </p>
 * 
 * <p>
 * Care must be taken to use the proper octets for line breaks if base64
 * encoding is applied directly to text material that has not been converted to
 * canonical form. In particular, text line breaks must be converted into CRLF
 * sequences prior to base64 encoding. The important thing to note is that this
 * may be done directly by the encoder rather than in a prior canonicalization
 * step in some implementations.
 * </p>
 * 
 * <p>
 * NOTE: There is no need to worry about quoting potential boundary delimiters
 * within base64-encoded bodies within multi-part entities because no hyphen
 * characters are used in the base64 encoding.
 * </p>
 * </blockquote>
 * 
 * @author Stephen Ostermiller
 *         http://ostermiller.org/contact.pl?regarding=Java+Utilities
 * @since ostermillerutils 1.00.00
 */
public class Base64
{

  /**
   * Symbol that represents the end of an input stream
   * 
   * @since ostermillerutils 1.00.00
   */
  private static final int END_OF_INPUT = -1;

  /**
   * A character that is not a valid base 64 character.
   * 
   * @since ostermillerutils 1.00.00
   */
  private static final int NON_BASE_64 = -1;

  /**
   * A character that is not a valid base 64 character.
   * 
   * @since ostermillerutils 1.00.00
   */
  private static final int NON_BASE_64_WHITESPACE = -2;

  /**
   * A character that is not a valid base 64 character.
   * 
   * @since ostermillerutils 1.00.00
   */
  private static final int NON_BASE_64_PADDING = -3;

  /**
   * This class need not be instantiated, all methods are static.
   * 
   * @since ostermillerutils 1.00.00
   */
  private Base64()
  {
    // should not be called
  }

  /**
   * Table of the sixty-four characters that are used as the Base64 alphabet:
   * [a-z0-9A-Z+/]
   * 
   * @since ostermillerutils 1.00.00
   */
  protected static final byte[] base64Chars =
  { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
          'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
          'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', };

  /**
   * Reverse lookup table for the Base64 alphabet. reversebase64Chars[byte]
   * gives n for the nth Base64 character or negative if a character is not a
   * Base64 character.
   * 
   * @since ostermillerutils 1.00.00
   */
  protected static final byte[] reverseBase64Chars = new byte[0x100];
  static
  {
    // Fill in NON_BASE_64 for all characters to start with
    for (int i = 0; i < reverseBase64Chars.length; i++)
    {
      reverseBase64Chars[i] = NON_BASE_64;
    }
    // For characters that are base64Chars, adjust
    // the reverse lookup table.
    for (byte i = 0; i < base64Chars.length; i++)
    {
      reverseBase64Chars[base64Chars[i]] = i;
    }
    reverseBase64Chars[' '] = NON_BASE_64_WHITESPACE;
    reverseBase64Chars['\n'] = NON_BASE_64_WHITESPACE;
    reverseBase64Chars['\r'] = NON_BASE_64_WHITESPACE;
    reverseBase64Chars['\t'] = NON_BASE_64_WHITESPACE;
    reverseBase64Chars['\f'] = NON_BASE_64_WHITESPACE;
    reverseBase64Chars['='] = NON_BASE_64_PADDING;
  }

  /**
   * Version number of this program
   * 
   * @since ostermillerutils 1.00.00
   */
  public static final String version = "1.2";

  /**
   * Encode a String in Base64. The String is converted to and from bytes
   * according to the platform's default character encoding. No line breaks or
   * other white space are inserted into the encoded data.
   * 
   * @param string
   *            The data to encode.
   * @return An encoded String.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static String encode(String string)
  {
    return new String(encode(string.getBytes()));
  }

  /**
   * Encode a String in Base64. No line breaks or other white space are
   * inserted into the encoded data.
   * 
   * @param string
   *            The data to encode.
   * @param enc
   *            Character encoding to use when converting to and from bytes.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * @return An encoded String.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static String encode(String string, String enc) throws UnsupportedEncodingException
  {
    return new String(encode(string.getBytes(enc)), enc);
  }

  /**
   * Encode bytes in Base64. No line breaks or other white space are inserted
   * into the encoded data.
   * 
   * @param bytes
   *            The data to encode.
   * @return String with Base64 encoded data.
   * 
   * @since ostermillerutils 1.04.00
   */
  public static String encodeToString(byte[] bytes)
  {
    return encodeToString(bytes, false);
  }

  /**
   * Encode bytes in Base64.
   * 
   * @param bytes
   *            The data to encode.
   * @param lineBreaks
   *            Whether to insert line breaks every 76 characters in the
   *            output.
   * @return String with Base64 encoded data.
   * 
   * @since ostermillerutils 1.04.00
   */
  public static String encodeToString(byte[] bytes, boolean lineBreaks)
  {
    try
    {
      return new String(encode(bytes, lineBreaks), "ASCII");
    } catch (UnsupportedEncodingException iex)
    {
      // ASCII should be supported
      throw new RuntimeException(iex);
    }
  }

  /**
   * Encode bytes in Base64. No line breaks or other white space are inserted
   * into the encoded data.
   * 
   * @param bytes
   *            The data to encode.
   * @return Encoded bytes.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static byte[] encode(byte[] bytes)
  {
    return encode(bytes, false);
  }

  /**
   * Encode bytes in Base64.
   * 
   * @param bytes
   *            The data to encode.
   * @param lineBreaks
   *            Whether to insert line breaks every 76 characters in the
   *            output.
   * @return Encoded bytes.
   * 
   * @since ostermillerutils 1.04.00
   */
  public static byte[] encode(byte[] bytes, boolean lineBreaks)
  {
    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    // calculate the length of the resulting output.
    // in general it will be 4/3 the size of the input
    // but the input length must be divisible by three.
    // If it isn't the next largest size that is divisible
    // by three is used.
    int mod;
    int length = bytes.length;
    if ((mod = length % 3) != 0)
    {
      length += 3 - mod;
    }
    length = length * 4 / 3;
    ByteArrayOutputStream out = new ByteArrayOutputStream(length);
    try
    {
      encode(in, out, lineBreaks);
    } catch (IOException x)
    {
      // This can't happen.
      // The input and output streams were constructed
      // on memory structures that don't actually use IO.
      throw new RuntimeException(x);
    }
    return out.toByteArray();
  }

  /**
   * Encode this file in Base64. Line breaks will be inserted every 76
   * characters.
   * 
   * @param fIn
   *            File to be encoded (will be overwritten).
   * @throws java.io.IOException
   *             if an input or output error occurs.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void encode(File fIn) throws IOException
  {
    encode(fIn, fIn, true);
  }

  /**
   * Encode this file in Base64.
   * 
   * @param fIn
   *            File to be encoded (will be overwritten).
   * @param lineBreaks
   *            Whether to insert line breaks every 76 characters in the
   *            output.
   * @throws java.io.IOException
   *             if an input or output error occurs.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void encode(File fIn, boolean lineBreaks) throws IOException
  {
    encode(fIn, fIn, lineBreaks);
  }

  /**
   * Encode this file in Base64. Line breaks will be inserted every 76
   * characters.
   * 
   * @param fIn
   *            File to be encoded.
   * @param fOut
   *            File to which the results should be written (may be the same
   *            as fIn).
   * @throws java.io.IOException
   *             if an input or output error occurs.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void encode(File fIn, File fOut) throws IOException
  {
    encode(fIn, fOut, true);
  }

  /**
   * Encode this file in Base64.
   * 
   * @param fIn
   *            File to be encoded.
   * @param fOut
   *            File to which the results should be written (may be the same
   *            as fIn).
   * @param lineBreaks
   *            Whether to insert line breaks every 76 characters in the
   *            output.
   * @throws java.io.IOException
   *             if an input or output error occurs.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void encode(File fIn, File fOut, boolean lineBreaks) throws IOException
  {
    File temp = null;
    InputStream in = null;
    OutputStream out = null;
    try
    {
      in = new BufferedInputStream(new FileInputStream(fIn));
      temp = File.createTempFile("Base64", null, null);
      out = new BufferedOutputStream(new FileOutputStream(temp));
      encode(in, out, lineBreaks);
      in.close();
      in = null;
      out.flush();
      out.close();
      out = null;
      FileHelper.move(temp, fOut, true);
    } finally
    {
      if (in != null)
      {
        in.close();
        in = null;
      }
      if (out != null)
      {
        out.flush();
        out.close();
        out = null;
      }
    }
  }

  /**
   * Encode data from the InputStream to the OutputStream in Base64. Line
   * breaks are inserted every 76 characters in the output.
   * 
   * @param in
   *            Stream from which to read data that needs to be encoded.
   * @param out
   *            Stream to which to write encoded data.
   * @throws java.io.IOException
   *             if there is a problem reading or writing.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void encode(InputStream in, OutputStream out) throws IOException
  {
    encode(in, out, true);
  }

  /**
   * Encode data from the InputStream to the OutputStream in Base64.
   * 
   * @param in
   *            Stream from which to read data that needs to be encoded.
   * @param out
   *            Stream to which to write encoded data.
   * @param lineBreaks
   *            Whether to insert line breaks every 76 characters in the
   *            output.
   * @throws java.io.IOException
   *             if there is a problem reading or writing.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void encode(InputStream in, OutputStream out, boolean lineBreaks) throws IOException
  {
    // Base64 encoding converts three bytes of input to
    // four bytes of output
    int[] inBuffer = new int[3];
    int lineCount = 0;

    boolean done = false;
    while (!done && (inBuffer[0] = in.read()) != END_OF_INPUT)
    {
      // Fill the buffer
      inBuffer[1] = in.read();
      inBuffer[2] = in.read();

      // Calculate the out Buffer
      // The first byte of our in buffer will always be valid
      // but we must check to make sure the other two bytes
      // are not END_OF_INPUT before using them.
      // The basic idea is that the three bytes get split into
      // four bytes along these lines:
      // [AAAAAABB] [BBBBCCCC] [CCDDDDDD]
      // [xxAAAAAA] [xxBBBBBB] [xxCCCCCC] [xxDDDDDD]
      // bytes are considered to be zero when absent.
      // the four bytes are then mapped to common ASCII symbols

      // A's: first six bits of first byte
      out.write(base64Chars[inBuffer[0] >> 2]);
      if (inBuffer[1] != END_OF_INPUT)
      {
        // B's: last two bits of first byte, first four bits of second
        // byte
        out.write(base64Chars[((inBuffer[0] << 4) & 0x30) | (inBuffer[1] >> 4)]);
        if (inBuffer[2] != END_OF_INPUT)
        {
          // C's: last four bits of second byte, first two bits of
          // third byte
          out.write(base64Chars[((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6)]);
          // D's: last six bits of third byte
          out.write(base64Chars[inBuffer[2] & 0x3F]);
        } else
        {
          // C's: last four bits of second byte
          out.write(base64Chars[((inBuffer[1] << 2) & 0x3c)]);
          // an equals sign for a character that is not a Base64
          // character
          out.write('=');
          done = true;
        }
      } else
      {
        // B's: last two bits of first byte
        out.write(base64Chars[((inBuffer[0] << 4) & 0x30)]);
        // an equal signs for characters that is not a Base64 characters
        out.write('=');
        out.write('=');
        done = true;
      }
      lineCount += 4;
      if (lineBreaks && lineCount >= 76)
      {
        out.write('\n');
        lineCount = 0;
      }
    }
    if (lineBreaks && lineCount >= 1)
    {
      out.write('\n');
      lineCount = 0;
    }
    out.flush();
  }

  /**
   * Decode a Base64 encoded String. Characters that are not part of the
   * Base64 alphabet are ignored in the input. The String is converted to and
   * from bytes according to the platform's default character encoding.
   * 
   * @param string
   *            The data to decode.
   * @return A decoded String.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static String decode(String string)
  {
    return new String(decode(string.getBytes()));
  }

  /**
   * Decode a Base64 encoded String. Characters that are not part of the
   * Base64 alphabet are ignored in the input.
   * 
   * @param string
   *            The data to decode.
   * @param enc
   *            Character encoding to use when converting to and from bytes.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * @return A decoded String.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static String decode(String string, String enc) throws UnsupportedEncodingException
  {
    return new String(decode(string.getBytes(enc)), enc);
  }

  /**
   * Decode a Base64 encoded String. Characters that are not part of the
   * Base64 alphabet are ignored in the input.
   * 
   * @param string
   *            The data to decode.
   * @param encIn
   *            Character encoding to use when converting input to bytes
   *            (should not matter because Base64 data is designed to survive
   *            most character encodings)
   * @param encOut
   *            Character encoding to use when converting decoded bytes to
   *            output.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * @return A decoded String.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static String decode(String string, String encIn, String encOut) throws UnsupportedEncodingException
  {
    return new String(decode(string.getBytes(encIn)), encOut);
  }

  /**
   * Decode a Base64 encoded String. Characters that are not part of the
   * Base64 alphabet are ignored in the input. The String is converted to and
   * from bytes according to the platform's default character encoding.
   * 
   * @param string
   *            The data to decode.
   * @return A decoded String.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static String decodeToString(String string)
  {
    return new String(decode(string.getBytes()));
  }

  /**
   * Decode a Base64 encoded String. Characters that are not part of the
   * Base64 alphabet are ignored in the input.
   * 
   * @param string
   *            The data to decode.
   * @param enc
   *            Character encoding to use when converting to and from bytes.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * @return A decoded String.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static String decodeToString(String string, String enc) throws UnsupportedEncodingException
  {
    return new String(decode(string.getBytes(enc)), enc);
  }

  /**
   * Decode a Base64 encoded String. Characters that are not part of the
   * Base64 alphabet are ignored in the input.
   * 
   * @param string
   *            The data to decode.
   * @param encIn
   *            Character encoding to use when converting input to bytes
   *            (should not matter because Base64 data is designed to survive
   *            most character encodings)
   * @param encOut
   *            Character encoding to use when converting decoded bytes to
   *            output.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * @return A decoded String.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static String decodeToString(String string, String encIn, String encOut) throws UnsupportedEncodingException
  {
    return new String(decode(string.getBytes(encIn)), encOut);
  }

  /**
   * Decode a Base64 encoded String to an OutputStream. Characters that are
   * not part of the Base64 alphabet are ignored in the input. The String is
   * converted from bytes according to the platform's default character
   * encoding.
   * 
   * @param string
   *            The data to decode.
   * @param out
   *            Stream to which to write decoded data.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static void decodeToStream(String string, OutputStream out) throws IOException
  {
    decode(new ByteArrayInputStream(string.getBytes()), out);
  }

  /**
   * Decode a Base64 encoded String to an OutputStream. Characters that are
   * not part of the Base64 alphabet are ignored in the input.
   * 
   * @param string
   *            The data to decode.
   * @param enc
   *            Character encoding to use when converting to and from bytes.
   * @param out
   *            Stream to which to write decoded data.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static void decodeToStream(String string, String enc, OutputStream out) throws UnsupportedEncodingException,
          IOException
  {
    decode(new ByteArrayInputStream(string.getBytes(enc)), out);
  }

  /**
   * Decode a Base64 encoded String. Characters that are not part of the
   * Base64 alphabet are ignored in the input. The String is converted from
   * bytes according to the platform's default character encoding.
   * 
   * @param string
   *            The data to decode.
   * @return decoded data.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static byte[] decodeToBytes(String string)
  {
    return decode(string.getBytes());
  }

  /**
   * Decode a Base64 encoded String. Characters that are not part of the
   * Base64 alphabet are ignored in the input.
   * 
   * @param string
   *            The data to decode.
   * @param enc
   *            Character encoding to use when converting from bytes.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * @return decoded data.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static byte[] decodeToBytes(String string, String enc) throws UnsupportedEncodingException
  {
    return decode(string.getBytes(enc));
  }

  /**
   * Decode Base64 encoded bytes. Characters that are not part of the Base64
   * alphabet are ignored in the input. The String is converted to bytes
   * according to the platform's default character encoding.
   * 
   * @param bytes
   *            The data to decode.
   * @return A decoded String.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static String decodeToString(byte[] bytes)
  {
    return new String(decode(bytes));
  }

  /**
   * Decode Base64 encoded bytes. Characters that are not part of the Base64
   * alphabet are ignored in the input.
   * 
   * @param bytes
   *            The data to decode.
   * @param enc
   *            Character encoding to use when converting to and from bytes.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * @return A decoded String.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static String decodeToString(byte[] bytes, String enc) throws UnsupportedEncodingException
  {
    return new String(decode(bytes), enc);
  }

  /**
   * Decode Base64 encoded bytes. Characters that are not part of the Base64
   * alphabet are ignored in the input.
   * 
   * @param bytes
   *            The data to decode.
   * @return Decoded bytes.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static byte[] decodeToBytes(byte[] bytes)
  {
    return decode(bytes);
  }

  /**
   * Decode Base64 encoded bytes. Characters that are not part of the Base64
   * alphabet are ignored in the input.
   * 
   * @param bytes
   *            The data to decode.
   * @return Decoded bytes.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static byte[] decode(byte[] bytes)
  {
    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    // calculate the length of the resulting output.
    // in general it will be at most 3/4 the size of the input
    // but the input length must be divisible by four.
    // If it isn't the next largest size that is divisible
    // by four is used.
    int mod;
    int length = bytes.length;
    if ((mod = length % 4) != 0)
    {
      length += 4 - mod;
    }
    length = length * 3 / 4;
    ByteArrayOutputStream out = new ByteArrayOutputStream(length);
    try
    {
      decode(in, out, false);
    } catch (IOException x)
    {
      // This can't happen.
      // The input and output streams were constructed
      // on memory structures that don't actually use IO.
      throw new RuntimeException(x);
    }
    return out.toByteArray();
  }

  /**
   * Decode Base64 encoded bytes to the an OutputStream. Characters that are
   * not part of the Base64 alphabet are ignored in the input.
   * 
   * @param bytes
   *            The data to decode.
   * @param out
   *            Stream to which to write decoded data.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void decode(byte[] bytes, OutputStream out) throws IOException
  {
    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    decode(in, out, false);
  }

  /**
   * Decode Base64 encoded bytes to the an OutputStream. Characters that are
   * not part of the Base64 alphabet are ignored in the input.
   * 
   * @param bytes
   *            The data to decode.
   * @param out
   *            Stream to which to write decoded data.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static void decodeToStream(byte[] bytes, OutputStream out) throws IOException
  {
    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    decode(in, out, false);
  }

  /**
   * Decode Base64 encoded data from one file to the other. Characters in the
   * Base64 alphabet, white space and equals sign are expected to be in url
   * encoded data. The presence of other characters could be a sign that the
   * data is corrupted.
   * 
   * @param fIn
   *            File to be decoded (will be overwritten).
   * @throws java.io.IOException
   *             if an IO error occurs.
   * @throws es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException
   *             if unexpected data is encountered.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void decode(File fIn) throws IOException
  {
    decode(fIn, fIn, true);
  }

  /**
   * Decode Base64 encoded data from one file to the other. Characters in the
   * Base64 alphabet, white space and equals sign are expected to be in url
   * encoded data. The presence of other characters could be a sign that the
   * data is corrupted.
   * 
   * @param fIn
   *            File to be decoded (will be overwritten).
   * @param throwExceptions
   *            Whether to throw exceptions when unexpected data is
   *            encountered.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * @throws es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException
   *             if unexpected data is encountered when throwExceptions is
   *             specified.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void decode(File fIn, boolean throwExceptions) throws IOException
  {
    decode(fIn, fIn, throwExceptions);
  }

  /**
   * Decode Base64 encoded data from one file to the other. Characters in the
   * Base64 alphabet, white space and equals sign are expected to be in url
   * encoded data. The presence of other characters could be a sign that the
   * data is corrupted.
   * 
   * @param fIn
   *            File to be decoded.
   * @param fOut
   *            File to which the results should be written (may be the same
   *            as fIn).
   * @throws java.io.IOException
   *             if an IO error occurs.
   * @throws es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException
   *             if unexpected data is encountered.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void decode(File fIn, File fOut) throws IOException
  {
    decode(fIn, fOut, true);
  }

  /**
   * Decode Base64 encoded data from one file to the other. Characters in the
   * Base64 alphabet, white space and equals sign are expected to be in url
   * encoded data. The presence of other characters could be a sign that the
   * data is corrupted.
   * 
   * @param fIn
   *            File to be decoded.
   * @param fOut
   *            File to which the results should be written (may be the same
   *            as fIn).
   * @param throwExceptions
   *            Whether to throw exceptions when unexpected data is
   *            encountered.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * @throws es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException
   *             if unexpected data is encountered when throwExceptions is
   *             specified.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void decode(File fIn, File fOut, boolean throwExceptions) throws IOException
  {
    File temp = null;
    InputStream in = null;
    OutputStream out = null;
    try
    {
      in = new BufferedInputStream(new FileInputStream(fIn));
      temp = File.createTempFile("Base64", null, null);
      out = new BufferedOutputStream(new FileOutputStream(temp));
      decode(in, out, throwExceptions);
      in.close();
      in = null;
      out.flush();
      out.close();
      out = null;
      FileHelper.move(temp, fOut, true);
    } finally
    {
      if (in != null)
      {
        try
        {
          in.close();
        } catch (IOException ignore)
        {
          if (throwExceptions)
            throw ignore;
        }
        in = null;
      }
      if (out != null)
      {
        try
        {
          out.flush();
          out.close();
        } catch (IOException ignore)
        {
          if (throwExceptions)
            throw ignore;
        }
        out = null;
      }
    }
  }

  /**
   * Reads the next (decoded) Base64 character from the input stream. Non
   * Base64 characters are skipped.
   * 
   * @param in
   *            Stream from which bytes are read.
   * @param throwExceptions
   *            Throw an exception if an unexpected character is encountered.
   * @return the next Base64 character from the stream or -1 if there are no
   *         more Base64 characters on the stream.
   * @throws java.io.IOException
   *             if an IO Error occurs.
   * @throws es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException
   *             if unexpected data is encountered when throwExceptions is
   *             specified.
   * 
   * @since ostermillerutils 1.00.00
   */
  private static final int readBase64(InputStream in, boolean throwExceptions) throws IOException
  {
    int read;
    int numPadding = 0;
    do
    {
      read = in.read();
      if (read == END_OF_INPUT)
        return END_OF_INPUT;
      read = reverseBase64Chars[(byte) read];
      if (throwExceptions && (read == NON_BASE_64 || (numPadding > 0 && read > NON_BASE_64)))
      {
        throw new Base64DecodingException(MessageFormat.format("unexpectedchar %s", (Object[]) new String[]
        { "'" + (char) read + "' (0x" + Integer.toHexString(read) + ")" }), (char) read);
      }
      if (read == NON_BASE_64_PADDING)
      {
        numPadding++;
      }
    } while (read <= NON_BASE_64);
    return read;
  }

  /**
   * Decode Base64 encoded data from the InputStream to a byte array.
   * Characters that are not part of the Base64 alphabet are ignored in the
   * input.
   * 
   * @param in
   *            Stream from which to read data that needs to be decoded.
   * @return decoded data.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static byte[] decodeToBytes(InputStream in) throws IOException
  {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    decode(in, out, false);
    return out.toByteArray();
  }

  /**
   * Decode Base64 encoded data from the InputStream to a String. Characters
   * that are not part of the Base64 alphabet are ignored in the input. Bytes
   * are converted to characters in the output String according to the
   * platform's default character encoding.
   * 
   * @param in
   *            Stream from which to read data that needs to be decoded.
   * @return decoded data.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static String decodeToString(InputStream in) throws IOException
  {
    return new String(decodeToBytes(in));
  }

  /**
   * Decode Base64 encoded data from the InputStream to a String. Characters
   * that are not part of the Base64 alphabet are ignored in the input.
   * 
   * @param in
   *            Stream from which to read data that needs to be decoded.
   * @param enc
   *            Character encoding to use when converting bytes to characters.
   * @return decoded data.
   * @throws java.io.IOException
   *             if an IO error occurs.Throws:
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   * 
   * @since ostermillerutils 1.02.16
   */
  public static String decodeToString(InputStream in, String enc) throws IOException
  {
    return new String(decodeToBytes(in), enc);
  }

  /**
   * Decode Base64 encoded data from the InputStream to the OutputStream.
   * Characters in the Base64 alphabet, white space and equals sign are
   * expected to be in url encoded data. The presence of other characters
   * could be a sign that the data is corrupted.
   * 
   * @param in
   *            Stream from which to read data that needs to be decoded.
   * @param out
   *            Stream to which to write decoded data.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * @throws es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException
   *             if unexpected data is encountered.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void decode(InputStream in, OutputStream out) throws IOException
  {
    decode(in, out, true);
  }

  /**
   * Decode Base64 encoded data from the InputStream to the OutputStream.
   * Characters in the Base64 alphabet, white space and equals sign are
   * expected to be in url encoded data. The presence of other characters
   * could be a sign that the data is corrupted.
   * 
   * @param in
   *            Stream from which to read data that needs to be decoded.
   * @param out
   *            Stream to which to write decoded data.
   * @param throwExceptions
   *            Whether to throw exceptions when unexpected data is
   *            encountered.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * @throws es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException
   *             if unexpected data is encountered when throwExceptions is
   *             specified.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static void decode(InputStream in, OutputStream out, boolean throwExceptions) throws IOException
  {
    // Base64 decoding converts four bytes of input to three bytes of output
    int[] inBuffer = new int[4];

    // read bytes unmapping them from their ASCII encoding in the process
    // we must read at least two bytes to be able to output anything
    boolean done = false;
    while (!done && (inBuffer[0] = readBase64(in, throwExceptions)) != END_OF_INPUT
            && (inBuffer[1] = readBase64(in, throwExceptions)) != END_OF_INPUT)
    {
      // Fill the buffer
      inBuffer[2] = readBase64(in, throwExceptions);
      inBuffer[3] = readBase64(in, throwExceptions);

      // Calculate the output
      // The first two bytes of our in buffer will always be valid
      // but we must check to make sure the other two bytes
      // are not END_OF_INPUT before using them.
      // The basic idea is that the four bytes will get reconstituted
      // into three bytes along these lines:
      // [xxAAAAAA] [xxBBBBBB] [xxCCCCCC] [xxDDDDDD]
      // [AAAAAABB] [BBBBCCCC] [CCDDDDDD]
      // bytes are considered to be zero when absent.

      // six A and two B
      out.write(inBuffer[0] << 2 | inBuffer[1] >> 4);
      if (inBuffer[2] != END_OF_INPUT)
      {
        // four B and four C
        out.write(inBuffer[1] << 4 | inBuffer[2] >> 2);
        if (inBuffer[3] != END_OF_INPUT)
        {
          // two C and six D
          out.write(inBuffer[2] << 6 | inBuffer[3]);
        } else
        {
          done = true;
        }
      } else
      {
        done = true;
      }
    }
    out.flush();
  }

  /**
   * Determines if the byte array is in base64 format.
   * <p>
   * Data will be considered to be in base64 format if it contains only base64
   * characters and whitespace with equals sign padding on the end so that the
   * number of base64 characters is divisible by four.
   * <p>
   * It is possible for data to be in base64 format but for it to not meet
   * these stringent requirements. It is also possible for data to meet these
   * requirements even though decoding it would not make any sense. This
   * method should be used as a guide but it is not authoritative because of
   * the possibility of these false positives and false negatives.
   * <p>
   * Additionally, extra data such as headers or footers may throw this method
   * off the scent and cause it to return false.
   * 
   * @param bytes
   *            data that could be in base64 format.
   * @return true iff the array appears to be in base64 format
   * 
   * @since ostermillerutils 1.00.00
   */
  public static boolean isBase64(byte[] bytes)
  {
    try
    {
      return isBase64(new ByteArrayInputStream(bytes));
    } catch (IOException x)
    {
      // This can't happen.
      // The input and output streams were constructed
      // on memory structures that don't actually use IO.
      return false;
    }
  }

  /**
   * Determines if the String is in base64 format. The String is converted to
   * and from bytes according to the platform's default character encoding.
   * <p>
   * Data will be considered to be in base64 format if it contains only base64
   * characters and whitespace with equals sign padding on the end so that the
   * number of base64 characters is divisible by four.
   * <p>
   * It is possible for data to be in base64 format but for it to not meet
   * these stringent requirements. It is also possible for data to meet these
   * requirements even though decoding it would not make any sense. This
   * method should be used as a guide but it is not authoritative because of
   * the possibility of these false positives and false negatives.
   * <p>
   * Additionally, extra data such as headers or footers may throw this method
   * off the scent and cause it to return false.
   * 
   * @param string
   *            String that may be in base64 format.
   * @return Best guess as to whether the data is in base64 format.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static boolean isBase64(String string)
  {
    return isBase64(string.getBytes());
  }

  /**
   * Determines if the String is in base64 format.
   * <p>
   * Data will be considered to be in base64 format if it contains only base64
   * characters and whitespace with equals sign padding on the end so that the
   * number of base64 characters is divisible by four.
   * <p>
   * It is possible for data to be in base64 format but for it to not meet
   * these stringent requirements. It is also possible for data to meet these
   * requirements even though decoding it would not make any sense. This
   * method should be used as a guide but it is not authoritative because of
   * the possibility of these false positives and false negatives.
   * <p>
   * Additionally, extra data such as headers or footers may throw this method
   * off the scent and cause it to return false.
   * 
   * @param string
   *            String that may be in base64 format.
   * @param enc
   *            Character encoding to use when converting to bytes.
   * @return Best guess as to whether the data is in base64 format.
   * @throws java.io.UnsupportedEncodingException
   *             if the character encoding specified is not supported.
   */
  public static boolean isBase64(String string, String enc) throws UnsupportedEncodingException
  {
    return isBase64(string.getBytes(enc));
  }

  /**
   * Determines if the File is in base64 format.
   * <p>
   * Data will be considered to be in base64 format if it contains only base64
   * characters and whitespace with equals sign padding on the end so that the
   * number of base64 characters is divisible by four.
   * <p>
   * It is possible for data to be in base64 format but for it to not meet
   * these stringent requirements. It is also possible for data to meet these
   * requirements even though decoding it would not make any sense. This
   * method should be used as a guide but it is not authoritative because of
   * the possibility of these false positives and false negatives.
   * <p>
   * Additionally, extra data such as headers or footers may throw this method
   * off the scent and cause it to return false.
   * 
   * @param fIn
   *            File that may be in base64 format.
   * @return Best guess as to whether the data is in base64 format.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static boolean isBase64(File fIn) throws IOException
  {
    return isBase64(new BufferedInputStream(new FileInputStream(fIn)));
  }

  /**
   * Reads data from the stream and determines if it is in base64 format.
   * <p>
   * Data will be considered to be in base64 format if it contains only base64
   * characters and whitespace with equals sign padding on the end so that the
   * number of base64 characters is divisible by four.
   * <p>
   * It is possible for data to be in base64 format but for it to not meet
   * these stringent requirements. It is also possible for data to meet these
   * requirements even though decoding it would not make any sense. This
   * method should be used as a guide but it is not authoritative because of
   * the possibility of these false positives and false negatives.
   * <p>
   * Additionally, extra data such as headers or footers may throw this method
   * off the scent and cause it to return false.
   * 
   * @param in
   *            Stream from which to read data to be tested.
   * @return Best guess as to whether the data is in base64 format.
   * @throws java.io.IOException
   *             if an IO error occurs.
   * 
   * @since ostermillerutils 1.00.00
   */
  public static boolean isBase64(InputStream in) throws IOException
  {
    long numBase64Chars = 0;
    int numPadding = 0;
    int read;

    while ((read = in.read()) != -1)
    {
      read = reverseBase64Chars[read];
      if (read == NON_BASE_64)
      {
        return false;
      } else if (read == NON_BASE_64_WHITESPACE)
      {
        // ignore white space
      } else if (read == NON_BASE_64_PADDING)
      {
        numPadding++;
        numBase64Chars++;
      } else if (numPadding > 0)
      {
        return false;
      } else
      {
        numBase64Chars++;
      }
    }
    if (numBase64Chars == 0)
      return false;
    if (numBase64Chars % 4 != 0)
      return false;
    return true;
  }
}




Java Source Code List

es.javocsoft.android.lib.toolbox.ToolBox.java
es.javocsoft.android.lib.toolbox.ads.AdBase.java
es.javocsoft.android.lib.toolbox.ads.AdFragment.java
es.javocsoft.android.lib.toolbox.ads.AdInterstitial.java
es.javocsoft.android.lib.toolbox.ads.InterstitialAdsListener.java
es.javocsoft.android.lib.toolbox.analytics.CampaignInfo.java
es.javocsoft.android.lib.toolbox.analytics.CustomCampaignTrackingReceiver.java
es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException.java
es.javocsoft.android.lib.toolbox.encoding.Base64.java
es.javocsoft.android.lib.toolbox.encoding.FileHelper.java
es.javocsoft.android.lib.toolbox.facebook.FacebookLoginFragment.java
es.javocsoft.android.lib.toolbox.facebook.FacebookShareFragment.java
es.javocsoft.android.lib.toolbox.facebook.FbTools.java
es.javocsoft.android.lib.toolbox.facebook.beans.AppRequestBean.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestCancelledActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestDeleteSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestFailActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestReceivedActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestReceivedErrorActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnLoginActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnLogoutActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareCancelledActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareFailActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.exception.FBException.java
es.javocsoft.android.lib.toolbox.facebook.exception.FBSessionException.java
es.javocsoft.android.lib.toolbox.gcm.EnvironmentType.java
es.javocsoft.android.lib.toolbox.gcm.NotificationModule.java
es.javocsoft.android.lib.toolbox.gcm.core.CustomGCMBroadcastReceiver.java
es.javocsoft.android.lib.toolbox.gcm.core.CustomNotificationReceiver.java
es.javocsoft.android.lib.toolbox.gcm.core.GCMIntentService.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMDeliveryResponse.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMDeliveryResultItem.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMMessage.java
es.javocsoft.android.lib.toolbox.gcm.exception.GCMException.java
es.javocsoft.android.lib.toolbox.gcm.send.GCMHttpDelivery.java
es.javocsoft.android.lib.toolbox.io.IOUtils.java
es.javocsoft.android.lib.toolbox.io.Unzipper.java
es.javocsoft.android.lib.toolbox.media.MediaScannerNotifier.java
es.javocsoft.android.lib.toolbox.net.HttpOperations.java
es.javocsoft.android.lib.toolbox.sms.cmt.CMTInfoHelper.java
es.javocsoft.android.lib.toolbox.sms.cmt.CMTShortNumberInformation.java
es.javocsoft.android.lib.toolbox.sms.observer.SMSObserver.java