首页

关于jgroups实现Base64加解密算法及相关转换处理方法源码分享

标签:Base64,加解密,JGroups     发布时间:2018-03-12   

一、前言

基于JGroups开源包org.jgroups.util.Base64加解密算法实现源码,详情参见源码说明。

二、源码说明

package org.jgroups.util;@b@@b@import java.io.BufferedInputStream;@b@import java.io.BufferedOutputStream;@b@import java.io.ByteArrayInputStream;@b@import java.io.ByteArrayOutputStream;@b@import java.io.File;@b@import java.io.FileInputStream;@b@import java.io.FileOutputStream;@b@import java.io.FilterInputStream;@b@import java.io.FilterOutputStream;@b@import java.io.IOException;@b@import java.io.InputStream;@b@import java.io.ObjectInputStream;@b@import java.io.ObjectOutputStream;@b@import java.io.ObjectStreamClass;@b@import java.io.OutputStream;@b@import java.io.Serializable;@b@import java.io.UnsupportedEncodingException;@b@import java.nio.ByteBuffer;@b@import java.nio.CharBuffer;@b@import java.util.zip.GZIPInputStream;@b@import java.util.zip.GZIPOutputStream;@b@@b@public final class Base64@b@{@b@  public static final int NO_OPTIONS = 0;@b@  public static final int ENCODE = 1;@b@  public static final int DECODE = 0;@b@  public static final int GZIP = 2;@b@  public static final int DONT_GUNZIP = 4;@b@  public static final int DO_BREAK_LINES = 8;@b@  public static final int URL_SAFE = 16;@b@  public static final int ORDERED = 32;@b@  private static final int MAX_LINE_LENGTH = 76;@b@  private static final byte EQUALS_SIGN = 61;@b@  private static final byte NEW_LINE = 10;@b@  private static final String PREFERRED_ENCODING = "US-ASCII";@b@  private static final byte WHITE_SPACE_ENC = -5;@b@  private static final byte EQUALS_SIGN_ENC = -1;@b@  private static final byte[] _STANDARD_ALPHABET;@b@  private static final byte[] _STANDARD_DECODABET;@b@  private static final byte[] _URL_SAFE_ALPHABET;@b@  private static final byte[] _URL_SAFE_DECODABET;@b@  private static final byte[] _ORDERED_ALPHABET;@b@  private static final byte[] _ORDERED_DECODABET;@b@@b@  private static final byte[] getAlphabet(int options)@b@  {@b@    if ((options & 0x10) == 16)@b@      return _URL_SAFE_ALPHABET;@b@    if ((options & 0x20) == 32)@b@      return _ORDERED_ALPHABET;@b@@b@    return _STANDARD_ALPHABET;@b@  }@b@@b@  private static final byte[] getDecodabet(int options)@b@  {@b@    if ((options & 0x10) == 16)@b@      return _URL_SAFE_DECODABET;@b@    if ((options & 0x20) == 32)@b@      return _ORDERED_DECODABET;@b@@b@    return _STANDARD_DECODABET;@b@  }@b@@b@  private static byte[] encode3to4(byte[] b4, byte[] threeBytes, int numSigBytes, int options)@b@  {@b@    encode3to4(threeBytes, 0, numSigBytes, b4, 0, options);@b@    return b4;@b@  }@b@@b@  private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset, int options)@b@  {@b@    byte[] ALPHABET = getAlphabet(options);@b@@b@    int inBuff = ((numSigBytes > 0) ? source[srcOffset] << 24 >>> 8 : 0) | ((numSigBytes > 1) ? source[(srcOffset + 1)] << 24 >>> 16 : 0) | ((numSigBytes > 2) ? source[(srcOffset + 2)] << 24 >>> 24 : 0);@b@@b@    switch (numSigBytes)@b@    {@b@    case 3:@b@      destination[destOffset] = ALPHABET[(inBuff >>> 18)];@b@      destination[(destOffset + 1)] = ALPHABET[(inBuff >>> 12 & 0x3F)];@b@      destination[(destOffset + 2)] = ALPHABET[(inBuff >>> 6 & 0x3F)];@b@      destination[(destOffset + 3)] = ALPHABET[(inBuff & 0x3F)];@b@      return destination;@b@    case 2:@b@      destination[destOffset] = ALPHABET[(inBuff >>> 18)];@b@      destination[(destOffset + 1)] = ALPHABET[(inBuff >>> 12 & 0x3F)];@b@      destination[(destOffset + 2)] = ALPHABET[(inBuff >>> 6 & 0x3F)];@b@      destination[(destOffset + 3)] = 61;@b@      return destination;@b@    case 1:@b@      destination[destOffset] = ALPHABET[(inBuff >>> 18)];@b@      destination[(destOffset + 1)] = ALPHABET[(inBuff >>> 12 & 0x3F)];@b@      destination[(destOffset + 2)] = 61;@b@      destination[(destOffset + 3)] = 61;@b@      return destination;@b@    }@b@@b@    return destination;@b@  }@b@@b@  public static void encode(ByteBuffer raw, ByteBuffer encoded)@b@  {@b@    byte[] raw3 = new byte[3];@b@    byte[] enc4 = new byte[4];@b@@b@    while (raw.hasRemaining()) {@b@      int rem = Math.min(3, raw.remaining());@b@      raw.get(raw3, 0, rem);@b@      encode3to4(enc4, raw3, rem, 0);@b@      encoded.put(enc4);@b@    }@b@  }@b@@b@  public static void encode(ByteBuffer raw, CharBuffer encoded)@b@  {@b@    int i;@b@    byte[] raw3 = new byte[3];@b@    byte[] enc4 = new byte[4];@b@@b@    while (raw.hasRemaining()) {@b@      int rem = Math.min(3, raw.remaining());@b@      raw.get(raw3, 0, rem);@b@      encode3to4(enc4, raw3, rem, 0);@b@      for (i = 0; i < 4; ++i)@b@        encoded.put((char)(enc4[i] & 0xFF));@b@    }@b@  }@b@@b@  public static String encodeObject(Serializable serializableObject)@b@    throws IOException@b@  {@b@    return encodeObject(serializableObject, 0);@b@  }@b@@b@  public static String encodeObject(Serializable serializableObject, int options)@b@    throws IOException@b@  {@b@    if (serializableObject == null) {@b@      throw new NullPointerException("Cannot serialize a null object.");@b@    }@b@@b@    ByteArrayOutputStream baos = null;@b@    OutputStream b64os = null;@b@    GZIPOutputStream gzos = null;@b@    ObjectOutputStream oos = null;@b@    try@b@    {@b@      baos = new ByteArrayOutputStream();@b@      b64os = new OutputStream(baos, 0x1 | options);@b@      if ((options & 0x2) != 0)@b@      {@b@        gzos = new GZIPOutputStream(b64os);@b@        oos = new ObjectOutputStream(gzos);@b@      }@b@      else {@b@        oos = new ObjectOutputStream(b64os);@b@      }@b@      oos.writeObject(serializableObject);@b@    }@b@    catch (IOException e)@b@    {@b@    }@b@    finally@b@    {@b@      try {@b@        oos.close(); } catch (Exception localException5) { }@b@      try { gzos.close(); } catch (Exception localException6) { }@b@      try { b64os.close(); } catch (Exception localException7) { }@b@      try { baos.close();@b@      } catch (Exception localException8) {@b@      }@b@    }@b@    try {@b@      return new String(baos.toByteArray(), "US-ASCII");@b@    }@b@    catch (UnsupportedEncodingException uue) {@b@    }@b@    return new String(baos.toByteArray());@b@  }@b@@b@  public static String encodeBytes(byte[] source)@b@  {@b@    String encoded = null;@b@    try {@b@      encoded = encodeBytes(source, 0, source.length, 0);@b@    } catch (IOException ex) {@b@      if (!($assertionsDisabled)) throw new AssertionError(ex.getMessage());@b@    }@b@    if ((!($assertionsDisabled)) && (encoded == null)) throw new AssertionError();@b@    return encoded;@b@  }@b@@b@  public static String encodeBytes(byte[] source, int options)@b@    throws IOException@b@  {@b@    return encodeBytes(source, 0, source.length, options);@b@  }@b@@b@  public static String encodeBytes(byte[] source, int off, int len)@b@  {@b@    String encoded = null;@b@    try {@b@      encoded = encodeBytes(source, off, len, 0);@b@    } catch (IOException ex) {@b@      if (!($assertionsDisabled)) throw new AssertionError(ex.getMessage());@b@    }@b@    if ((!($assertionsDisabled)) && (encoded == null)) throw new AssertionError();@b@    return encoded;@b@  }@b@@b@  public static String encodeBytes(byte[] source, int off, int len, int options)@b@    throws IOException@b@  {@b@    byte[] encoded = encodeBytesToBytes(source, off, len, options);@b@    try@b@    {@b@      return new String(encoded, "US-ASCII");@b@    } catch (UnsupportedEncodingException uue) {@b@    }@b@    return new String(encoded);@b@  }@b@@b@  public static byte[] encodeBytesToBytes(byte[] source)@b@  {@b@    byte[] encoded = null;@b@    try {@b@      encoded = encodeBytesToBytes(source, 0, source.length, 0);@b@    } catch (IOException ex) {@b@      if (!($assertionsDisabled)) throw new AssertionError("IOExceptions only come from GZipping, which is turned off: " + ex.getMessage());@b@    }@b@    return encoded;@b@  }@b@@b@  public static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options)@b@    throws IOException@b@  {@b@    int i;@b@    int j;@b@    if (source == null) {@b@      throw new NullPointerException("Cannot serialize a null array.");@b@    }@b@@b@    if (off < 0) {@b@      throw new IllegalArgumentException("Cannot have negative offset: " + off);@b@    }@b@@b@    if (len < 0) {@b@      throw new IllegalArgumentException("Cannot have length offset: " + len);@b@    }@b@@b@    if (off + len > source.length)@b@    {@b@      throw new IllegalArgumentException(String.format("Cannot have offset of %d and length of %d with array of length %d", new Object[] { @b@        Integer.valueOf(off), @b@        Integer.valueOf(len), Integer.valueOf(source.length) }));@b@    }@b@@b@    if ((options & 0x2) != 0) {@b@      ByteArrayOutputStream baos = null;@b@      GZIPOutputStream gzos = null;@b@      OutputStream b64os = null;@b@      try@b@      {@b@        baos = new ByteArrayOutputStream();@b@        b64os = new OutputStream(baos, 0x1 | options);@b@        gzos = new GZIPOutputStream(b64os);@b@@b@        gzos.write(source, off, len);@b@        gzos.close();@b@      }@b@      catch (IOException e)@b@      {@b@      }@b@      finally@b@      {@b@        try {@b@          gzos.close(); } catch (Exception localException4) { }@b@        try { b64os.close(); } catch (Exception localException5) { }@b@        try { baos.close(); } catch (Exception localException6) {@b@        }@b@      }@b@      return baos.toByteArray();@b@    }@b@@b@    boolean breakLines = (options & 0x8) != 0;@b@@b@    int encLen = len / 3 * 4 + ((len % 3 > 0) ? 4 : 0);@b@    if (breakLines)@b@      encLen += encLen / 76;@b@@b@    byte[] outBuff = new byte[encLen];@b@@b@    int i = 0;@b@    int j = 0;@b@    int len2 = len - 2;@b@    int lineLength = 0;@b@    while (i < len2) {@b@      encode3to4(source, i + off, 3, outBuff, j, options);@b@@b@      lineLength += 4;@b@      if ((breakLines) && (lineLength >= 76))@b@      {@b@        outBuff[(j + 4)] = 10;@b@        ++j;@b@        lineLength = 0;@b@      }@b@      i += 3; j += 4;@b@    }@b@@b@    if (i < len) {@b@      encode3to4(source, i + off, len - i, outBuff, j, options);@b@      j += 4;@b@    }@b@@b@    if (j <= outBuff.length - 1)@b@    {@b@      byte[] finalOut = new byte[j];@b@      System.arraycopy(outBuff, 0, finalOut, 0, j);@b@@b@      return finalOut;@b@    }@b@@b@    return outBuff;@b@  }@b@@b@  private static int decode4to3(byte[] source, int srcOffset, byte[] destination, int destOffset, int options)@b@  {@b@    if (source == null)@b@      throw new NullPointerException("Source array was null.");@b@@b@    if (destination == null)@b@      throw new NullPointerException("Destination array was null.");@b@@b@    if ((srcOffset < 0) || (srcOffset + 3 >= source.length))@b@      throw new IllegalArgumentException(String.format("Source array with length %d cannot have offset of %d and still process four bytes.", new Object[] { @b@        Integer.valueOf(source.length), @b@        Integer.valueOf(srcOffset) }));@b@@b@    if ((destOffset < 0) || (destOffset + 2 >= destination.length)) {@b@      throw new IllegalArgumentException(String.format("Destination array with length %d cannot have offset of %d and still store three bytes.", new Object[] { @b@        Integer.valueOf(destination.length), @b@        Integer.valueOf(destOffset) }));@b@    }@b@@b@    byte[] DECODABET = getDecodabet(options);@b@@b@    if (source[(srcOffset + 2)] == 61)@b@    {@b@      outBuff = (DECODABET[source[srcOffset]] & 0xFF) << 18 | (DECODABET[source[(srcOffset + 1)]] & 0xFF) << 12;@b@@b@      destination[destOffset] = (byte)(outBuff >>> 16);@b@      return 1;@b@    }@b@@b@    if (source[(srcOffset + 3)] == 61)@b@    {@b@      outBuff = (DECODABET[source[srcOffset]] & 0xFF) << 18 | (DECODABET[source[(srcOffset + 1)]] & 0xFF) << 12 | (DECODABET[source[(srcOffset + 2)]] & 0xFF) << 6;@b@@b@      destination[destOffset] = (byte)(outBuff >>> 16);@b@      destination[(destOffset + 1)] = (byte)(outBuff >>> 8);@b@      return 2;@b@    }@b@@b@    int outBuff = (DECODABET[source[srcOffset]] & 0xFF) << 18 | (DECODABET[source[(srcOffset + 1)]] & 0xFF) << 12 | (DECODABET[source[(srcOffset + 2)]] & 0xFF) << 6 | DECODABET[source[(srcOffset + 3)]] & 0xFF;@b@@b@    destination[destOffset] = (byte)(outBuff >> 16);@b@    destination[(destOffset + 1)] = (byte)(outBuff >> 8);@b@    destination[(destOffset + 2)] = (byte)outBuff;@b@@b@    return 3;@b@  }@b@@b@  public static byte[] decode(byte[] source)@b@    throws IOException@b@  {@b@    byte[] decoded = null;@b@@b@    decoded = decode(source, 0, source.length, 0);@b@@b@    return decoded;@b@  }@b@@b@  public static byte[] decode(byte[] source, int off, int len, int options)@b@    throws IOException@b@  {@b@    if (source == null)@b@      throw new NullPointerException("Cannot decode null source array.");@b@@b@    if ((off < 0) || (off + len > source.length)) {@b@      throw new IllegalArgumentException(String.format("Source array with length %d cannot have offset of %d and process %d bytes.", new Object[] { @b@        Integer.valueOf(source.length), @b@        Integer.valueOf(off), Integer.valueOf(len) }));@b@    }@b@@b@    if (len == 0)@b@      return new byte[0];@b@    if (len < 4) {@b@      throw new IllegalArgumentException("Base64-encoded string must have at least four characters, but length specified was " + len);@b@    }@b@@b@    byte[] DECODABET = getDecodabet(options);@b@@b@    int len34 = len * 3 / 4;@b@    byte[] outBuff = new byte[len34];@b@    int outBuffPosn = 0;@b@@b@    byte[] b4 = new byte[4];@b@    int b4Posn = 0;@b@    int i = 0;@b@    byte sbiDecode = 0;@b@@b@    for (i = off; i < off + len; ++i)@b@    {@b@      sbiDecode = DECODABET[(source[i] & 0xFF)];@b@@b@      if (sbiDecode >= -5) {@b@        if (sbiDecode < -1) break label266;@b@        b4[(b4Posn++)] = source[i];@b@        if (b4Posn <= 3) break label266;@b@        outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options);@b@        b4Posn = 0;@b@@b@        if (source[i] != 61) break label266;@b@        break;@b@      }@b@@b@      throw new IOException(String.format("Bad Base64 input character decimal %d in array position %d", new Object[] { @b@        Integer.valueOf(source[i] & 0xFF), @b@        Integer.valueOf(i) }));@b@    }@b@@b@    label266: byte[] out = new byte[outBuffPosn];@b@    System.arraycopy(outBuff, 0, out, 0, outBuffPosn);@b@    return out;@b@  }@b@@b@  public static byte[] decode(String s)@b@    throws IOException@b@  {@b@    return decode(s, 0);@b@  }@b@@b@  public static byte[] decode(String s, int options)@b@    throws IOException@b@  {@b@    if (s == null) {@b@      throw new NullPointerException("Input string was null.");@b@    }@b@@b@    try@b@    {@b@      bytes = s.getBytes("US-ASCII");@b@    }@b@    catch (UnsupportedEncodingException uee) {@b@      bytes = s.getBytes();@b@    }@b@@b@    byte[] bytes = decode(bytes, 0, bytes.length, options);@b@@b@    boolean dontGunzip = (options & 0x4) != 0;@b@    if ((bytes != null) && (bytes.length >= 4) && (!(dontGunzip)))@b@    {@b@      int head = bytes[0] & 0xFF | bytes[1] << 8 & 0xFF00;@b@      if (35615 == head) {@b@        ByteArrayInputStream bais = null;@b@        GZIPInputStream gzis = null;@b@        ByteArrayOutputStream baos = null;@b@        byte[] buffer = new byte[2048];@b@        int length = 0;@b@        try@b@        {@b@          baos = new ByteArrayOutputStream();@b@          bais = new ByteArrayInputStream(bytes);@b@          gzis = new GZIPInputStream(bais);@b@@b@          while ((length = gzis.read(buffer)) >= 0) {@b@            baos.write(buffer, 0, length);@b@          }@b@@b@          bytes = baos.toByteArray();@b@        }@b@        catch (IOException e)@b@        {@b@          e.printStackTrace();@b@        }@b@        finally {@b@          try {@b@            baos.close(); } catch (Exception localException4) { }@b@          try { gzis.close(); } catch (Exception localException5) { }@b@          try { bais.close();@b@          } catch (Exception localException6) {@b@          }@b@        }@b@      }@b@    }@b@    return bytes;@b@  }@b@@b@  public static Object decodeToObject(String encodedObject)@b@    throws IOException, ClassNotFoundException@b@  {@b@    return decodeToObject(encodedObject, 0, null);@b@  }@b@@b@  public static Object decodeToObject(String encodedObject, int options, ClassLoader loader)@b@    throws IOException, ClassNotFoundException@b@  {@b@    byte[] objBytes = decode(encodedObject, options);@b@@b@    ByteArrayInputStream bais = null;@b@    ObjectInputStream ois = null;@b@    Object obj = null;@b@    try@b@    {@b@      bais = new ByteArrayInputStream(objBytes);@b@@b@      if (loader == null) {@b@        ois = new ObjectInputStream(bais);@b@      }@b@      else@b@      {@b@        ois = new ObjectInputStream(bais, loader)@b@        {@b@          public Class<?> resolveClass(ObjectStreamClass streamClass) throws IOException, ClassNotFoundException@b@          {@b@            Class c = Class.forName(streamClass.getName(), false, this.val$loader);@b@            if (c == null)@b@              return super.resolveClass(streamClass);@b@@b@            return c;@b@          }@b@@b@        };@b@      }@b@@b@      obj = ois.readObject();@b@    }@b@    catch (ClassNotFoundException e)@b@    {@b@    }@b@    finally {@b@      try {@b@        bais.close(); } catch (Exception localException3) { }@b@      try { ois.close(); } catch (Exception localException4) {@b@      }@b@    }@b@    return obj;@b@  }@b@@b@  public static void encodeToFile(byte[] dataToEncode, String filename)@b@    throws IOException@b@  {@b@    if (dataToEncode == null) {@b@      throw new NullPointerException("Data to encode was null.");@b@    }@b@@b@    OutputStream bos = null;@b@    try {@b@      bos = new OutputStream(new FileOutputStream(filename), 1);@b@@b@      bos.write(dataToEncode);@b@    }@b@    catch (IOException e) {@b@    }@b@    finally {@b@      try {@b@        bos.close();@b@      }@b@      catch (Exception localException2)@b@      {@b@      }@b@    }@b@  }@b@@b@  public static void decodeToFile(String dataToDecode, String filename)@b@    throws IOException@b@  {@b@    OutputStream bos = null;@b@    try {@b@      bos = new OutputStream(new FileOutputStream(filename), 0);@b@@b@      bos.write(dataToDecode.getBytes("US-ASCII"));@b@    }@b@    catch (IOException e) {@b@    }@b@    finally {@b@      try {@b@        bos.close();@b@      }@b@      catch (Exception localException2)@b@      {@b@      }@b@    }@b@  }@b@@b@  public static byte[] decodeFromFile(String filename)@b@    throws IOException@b@  {@b@    byte[] decodedData = null;@b@    InputStream bis = null;@b@    try@b@    {@b@      file = new File(filename);@b@      byte[] buffer = null;@b@      int length = 0;@b@      int numBytes = 0;@b@@b@      if (file.length() > 2147483647L)@b@      {@b@        throw new IOException("File is too big for this convenience method (" + file.length() + " bytes).");@b@      }@b@      buffer = new byte[(int)file.length()];@b@@b@      bis = new InputStream(new BufferedInputStream(new FileInputStream(file)), 0);@b@@b@      while ((numBytes = bis.read(buffer, length, 4096)) >= 0) {@b@        length += numBytes;@b@      }@b@@b@      decodedData = new byte[length];@b@      System.arraycopy(buffer, 0, decodedData, 0, length);@b@    }@b@    catch (IOException e)@b@    {@b@    }@b@    finally {@b@      try {@b@        bis.close(); } catch (Exception localException) {@b@      }@b@    }@b@    return decodedData;@b@  }@b@@b@  public static String encodeFromFile(String filename)@b@    throws IOException@b@  {@b@    String encodedData = null;@b@    InputStream bis = null;@b@    try@b@    {@b@      file = new File(filename);@b@      byte[] buffer = new byte[Math.max((int)(file.length() * 1.4D + 1.0D), 40)];@b@      int length = 0;@b@      int numBytes = 0;@b@@b@      bis = new InputStream(new BufferedInputStream(new FileInputStream(file)), 1);@b@@b@      while ((numBytes = bis.read(buffer, length, 4096)) >= 0) {@b@        length += numBytes;@b@      }@b@@b@      encodedData = new String(buffer, 0, length, "US-ASCII");@b@    }@b@    catch (IOException e)@b@    {@b@    }@b@    finally {@b@      try {@b@        bis.close(); } catch (Exception localException) {@b@      }@b@    }@b@    return encodedData;@b@  }@b@@b@  public static void encodeFileToFile(String infile, String outfile)@b@    throws IOException@b@  {@b@    String encoded = encodeFromFile(infile);@b@    OutputStream out = null;@b@    try {@b@      out = new BufferedOutputStream(new FileOutputStream(outfile));@b@@b@      out.write(encoded.getBytes("US-ASCII"));@b@    }@b@    catch (IOException e) {@b@    }@b@    finally {@b@      try {@b@        out.close();@b@      }@b@      catch (Exception localException2)@b@      {@b@      }@b@    }@b@  }@b@@b@  public static void decodeFileToFile(String infile, String outfile)@b@    throws IOException@b@  {@b@    byte[] decoded = decodeFromFile(infile);@b@    OutputStream out = null;@b@    try {@b@      out = new BufferedOutputStream(new FileOutputStream(outfile));@b@@b@      out.write(decoded);@b@    }@b@    catch (IOException e) {@b@    }@b@    finally {@b@      try {@b@        out.close();@b@      }@b@      catch (Exception localException2)@b@      {@b@      }@b@    }@b@  }@b@@b@  static@b@  {@b@    _STANDARD_ALPHABET = new byte[] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 };@b@@b@    _STANDARD_DECODABET = new byte[] { -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -5, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 62, -9, -9, -9, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -9, -9, -9, -1, -9, -9, -9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -9, -9, -9, -9, -9, -9, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 };@b@@b@    _URL_SAFE_ALPHABET = new byte[] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95 };@b@@b@    _URL_SAFE_DECODABET = new byte[] { -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -5, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 62, -9, -9, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -9, -9, -9, -1, -9, -9, -9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -9, -9, -9, -9, 63, -9, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 };@b@@b@    _ORDERED_ALPHABET = new byte[] { 45, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122 };@b@@b@    _ORDERED_DECODABET = new byte[] { -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -5, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 0, -9, -9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -9, -9, -9, -1, -9, -9, -9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, -9, -9, -9, -9, 37, -9, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 };@b@  }@b@@b@  public static class OutputStream extends FilterOutputStream@b@  {@b@    private boolean encode;@b@    private int position;@b@    private byte[] buffer;@b@    private int bufferLength;@b@    private int lineLength;@b@    private boolean breakLines;@b@    private byte[] b4;@b@    private boolean suspendEncoding;@b@    private int options;@b@    private byte[] decodabet;@b@@b@    public OutputStream(OutputStream out)@b@    {@b@      this(out, 1);@b@    }@b@@b@    public OutputStream(OutputStream out, int options)@b@    {@b@      super(out);@b@      this.breakLines = ((options & 0x8) != 0);@b@      this.encode = ((options & 0x1) != 0);@b@      this.bufferLength = ((this.encode) ? 3 : 4);@b@      this.buffer = new byte[this.bufferLength];@b@      this.position = 0;@b@      this.lineLength = 0;@b@      this.suspendEncoding = false;@b@      this.b4 = new byte[4];@b@      this.options = options;@b@      this.decodabet = Base64.access$000(options);@b@    }@b@@b@    public void write(int theByte)@b@      throws IOException@b@    {@b@      if (this.suspendEncoding) {@b@        this.out.write(theByte);@b@        return;@b@      }@b@@b@      if (this.encode) {@b@        this.buffer[(this.position++)] = (byte)theByte;@b@        if (this.position >= this.bufferLength)@b@        {@b@          this.out.write(Base64.access$300(this.b4, this.buffer, this.bufferLength, this.options));@b@@b@          this.lineLength += 4;@b@          if ((this.breakLines) && (this.lineLength >= 76)) {@b@            this.out.write(10);@b@            this.lineLength = 0;@b@          }@b@@b@          this.position = 0;@b@        }@b@@b@      }@b@      else if (this.decodabet[(theByte & 0x7F)] > -5) {@b@        this.buffer[(this.position++)] = (byte)theByte;@b@        if (this.position >= this.bufferLength)@b@        {@b@          int len = Base64.access$200(this.buffer, 0, this.b4, 0, this.options);@b@          this.out.write(this.b4, 0, len);@b@          this.position = 0;@b@        }@b@      }@b@      else if (this.decodabet[(theByte & 0x7F)] != -5) {@b@        throw new IOException("Invalid character in Base64 data.");@b@      }@b@    }@b@@b@    public void write(byte[] theBytes, int off, int len)@b@      throws IOException@b@    {@b@      if (this.suspendEncoding) {@b@        this.out.write(theBytes, off, len);@b@        return;@b@      }@b@@b@      for (int i = 0; i < len; ++i)@b@        write(theBytes[(off + i)]);@b@    }@b@@b@    public void flushBase64()@b@      throws IOException@b@    {@b@      if (this.position > 0)@b@        if (this.encode) {@b@          this.out.write(Base64.access$300(this.b4, this.buffer, this.position, this.options));@b@          this.position = 0;@b@        }@b@        else {@b@          throw new IOException("Base64 input not properly padded.");@b@        }@b@    }@b@@b@    public void close()@b@      throws IOException@b@    {@b@      flushBase64();@b@@b@      super.close();@b@@b@      this.buffer = null;@b@      this.out = null;@b@    }@b@@b@    public void suspendEncoding()@b@      throws IOException@b@    {@b@      flushBase64();@b@      this.suspendEncoding = true;@b@    }@b@@b@    public void resumeEncoding()@b@    {@b@      this.suspendEncoding = false;@b@    }@b@  }@b@@b@  public static class InputStream extends FilterInputStream@b@  {@b@    private boolean encode;@b@    private int position;@b@    private byte[] buffer;@b@    private int bufferLength;@b@    private int numSigBytes;@b@    private int lineLength;@b@    private boolean breakLines;@b@    private int options;@b@    private byte[] decodabet;@b@@b@    public InputStream(InputStream in)@b@    {@b@      this(in, 0);@b@    }@b@@b@    public InputStream(InputStream in, int options)@b@    {@b@      super(in);@b@      this.options = options;@b@      this.breakLines = ((options & 0x8) > 0);@b@      this.encode = ((options & 0x1) > 0);@b@      this.bufferLength = ((this.encode) ? 4 : 3);@b@      this.buffer = new byte[this.bufferLength];@b@      this.position = -1;@b@      this.lineLength = 0;@b@      this.decodabet = Base64.access$000(options);@b@    }@b@@b@    public int read()@b@      throws IOException@b@    {@b@      if (this.position < 0) {@b@        if (this.encode) {@b@          byte[] b3 = new byte[3];@b@          int numBinaryBytes = 0;@b@          for (int i = 0; i < 3; ++i) {@b@            int b = this.in.read();@b@@b@            if (b < 0) break;@b@            b3[i] = (byte)b;@b@            ++numBinaryBytes;@b@          }@b@@b@          if (numBinaryBytes > 0) {@b@            Base64.access$100(b3, 0, numBinaryBytes, this.buffer, 0, this.options);@b@            this.position = 0;@b@            this.numSigBytes = 4;@b@          }@b@          else {@b@            return -1;@b@          }@b@@b@        }@b@        else@b@        {@b@          byte[] b4 = new byte[4];@b@          int i = 0;@b@          for (i = 0; i < 4; ++i)@b@          {@b@            int b = 0;@b@            do b = this.in.read();@b@            while ((b >= 0) && (this.decodabet[(b & 0x7F)] <= -5));@b@@b@            if (b < 0) {@b@              break;@b@            }@b@@b@            b4[i] = (byte)b;@b@          }@b@@b@          if (i == 4) {@b@            this.numSigBytes = Base64.access$200(b4, 0, this.buffer, 0, this.options);@b@            this.position = 0;@b@          } else {@b@            if (i == 0) {@b@              return -1;@b@            }@b@@b@            throw new IOException("Improperly padded Base64 input.");@b@          }@b@@b@        }@b@@b@      }@b@@b@      if (this.position >= 0)@b@      {@b@        if (this.position >= this.numSigBytes) {@b@          return -1;@b@        }@b@@b@        if ((this.encode) && (this.breakLines) && (this.lineLength >= 76)) {@b@          this.lineLength = 0;@b@          return 10;@b@        }@b@@b@        this.lineLength += 1;@b@@b@        int b = this.buffer[(this.position++)];@b@@b@        if (this.position >= this.bufferLength) {@b@          this.position = -1;@b@        }@b@@b@        return (b & 0xFF);@b@      }@b@@b@      throw new IOException("Error in Base64 code reading stream.");@b@    }@b@@b@    public int read(byte[] dest, int off, int len)@b@      throws IOException@b@    {@b@      for (int i = 0; i < len; ++i) {@b@        int b = read();@b@@b@        if (b >= 0) {@b@          dest[(off + i)] = (byte)b;@b@        } else {@b@          if (i != 0) break;@b@          return -1;@b@        }@b@@b@      }@b@@b@      return i;@b@    }@b@  }@b@}