一、前言
关于smack的smack-java源码包中org.jivesoftware.smack.util.stringencoder.java7.Base64、org.jivesoftware.smack.util.stringencoder.java7.Java7Base64Encoder及org.jivesoftware.smack.util.stringencoder.java7.Java7Base64UrlSafeEncoder加解密源码说明。
二、源码说明
1.Base64类
package org.jivesoftware.smack.util.stringencoder.java7;@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.OutputStream;@b@import java.io.Serializable;@b@import java.io.UnsupportedEncodingException;@b@import java.nio.charset.Charset;@b@import java.util.logging.Level;@b@import java.util.logging.Logger;@b@import java.util.zip.GZIPInputStream;@b@import java.util.zip.GZIPOutputStream;@b@@b@public final class Base64@b@{@b@ private static final Logger LOGGER = Logger.getLogger(Base64.class.getName());@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_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 = "UTF-8";@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 = { 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@ private static final byte[] _STANDARD_DECODABET = { -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 };@b@ private static final byte[] _URL_SAFE_ALPHABET = { 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@ private static final byte[] _URL_SAFE_DECODABET = { -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 };@b@ private static final byte[] _ORDERED_ALPHABET = { 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@ private static final byte[] _ORDERED_DECODABET = { -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 };@b@@b@ private static byte[] getAlphabet(int options)@b@ {@b@ if ((options & 0x10) == 16) return _URL_SAFE_ALPHABET;@b@ if ((options & 0x20) == 32) return _ORDERED_ALPHABET;@b@ return _STANDARD_ALPHABET;@b@ }@b@@b@ private static byte[] getDecodabet(int options)@b@ {@b@ if ((options & 0x10) == 16) return _URL_SAFE_DECODABET;@b@ if ((options & 0x20) == 32) return _ORDERED_DECODABET;@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) ? @b@ source[(srcOffset + 1)] << 24 >>> 16 : 0) | ((numSigBytes > 2) ? @b@ 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 String encodeObject(Serializable serializableObject)@b@ {@b@ return encodeObject(serializableObject, 0);@b@ }@b@@b@ public static String encodeObject(Serializable serializableObject, int options)@b@ {@b@ ByteArrayOutputStream baos = null;@b@ OutputStream b64os = null;@b@ ObjectOutputStream oos = null;@b@ GZIPOutputStream gzos = null;@b@@b@ int gzip = options & 0x2;@b@ try@b@ {@b@ baos = new ByteArrayOutputStream();@b@ b64os = new OutputStream(baos, 0x1 | options);@b@@b@ if (gzip == 2)@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@ LOGGER.log(Level.SEVERE, "Error encoding object", e);@b@ Object localObject1 = null;@b@@b@ return localObject1;@b@ }@b@ finally@b@ {@b@ try@b@ {@b@ oos.close(); } catch (Exception localException9) { }@b@ try { gzos.close(); } catch (Exception localException10) { }@b@ try { b64os.close(); } catch (Exception localException11) { }@b@ try { baos.close();@b@ }@b@ catch (Exception localException12) {@b@ }@b@ }@b@ try {@b@ return new String(baos.toByteArray(), "UTF-8");@b@ }@b@ catch (UnsupportedEncodingException uue) {@b@ }@b@ return new String(baos.toByteArray(), Charset.defaultCharset());@b@ }@b@@b@ public static String encodeBytes(byte[] source)@b@ {@b@ return encodeBytes(source, 0, source.length, 0);@b@ }@b@@b@ public static String encodeBytes(byte[] source, int options)@b@ {@b@ return encodeBytes(source, 0, source.length, options);@b@ }@b@@b@ public static String encodeBytes(byte[] source, int off, int len)@b@ {@b@ return encodeBytes(source, off, len, 0);@b@ }@b@@b@ public static String encodeBytes(byte[] source, int off, int len, int options)@b@ {@b@ int i;@b@ int j;@b@ int k;@b@ int dontBreakLines = options & 0x8;@b@ int gzip = options & 0x2;@b@@b@ if (gzip == 2)@b@ {@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@ LOGGER.log(Level.SEVERE, "Error encoding bytes", e);@b@ Object localObject1 = null;@b@@b@ return localObject1;@b@ }@b@ finally@b@ {@b@ try@b@ {@b@ gzos.close(); } catch (Exception localException7) { }@b@ try { b64os.close(); } catch (Exception localException8) { }@b@ try { baos.close();@b@ }@b@ catch (Exception localException9) {@b@ }@b@ }@b@ try {@b@ return new String(baos.toByteArray(), "UTF-8");@b@ }@b@ catch (UnsupportedEncodingException uue)@b@ {@b@ return new String(baos.toByteArray(), Charset.defaultCharset());@b@ }@b@@b@ }@b@@b@ boolean breakLines = dontBreakLines == 0;@b@@b@ int len43 = len * 4 / 3;@b@@b@ byte[] outBuff = new byte[len43 + ((len % 3 > 0) ? @b@ 4 : 0) + ((breakLines) ? @b@ len43 / 76 : 0)];@b@ int i = 0;@b@ int j = 0;@b@ int len2 = len - 2;@b@ int k = 0;@b@ while (i < len2)@b@ {@b@ encode3to4(source, i + off, 3, outBuff, j, options);@b@@b@ k += 4;@b@ if ((breakLines) && (k == 76))@b@ {@b@ outBuff[(j + 4)] = 10;@b@ ++j;@b@ k = 0;@b@ }@b@ i += 3; j += 4;@b@ }@b@@b@ if (i < len)@b@ {@b@ encode3to4(source, i + off, len - i, outBuff, j, options);@b@ j += 4;@b@ }@b@@b@ try@b@ {@b@ return new String(outBuff, 0, j, "UTF-8");@b@ }@b@ catch (UnsupportedEncodingException uue) {@b@ }@b@ return new String(outBuff, 0, j, Charset.defaultCharset());@b@ }@b@@b@ private static int decode4to3(byte[] source, int srcOffset, byte[] destination, int destOffset, int options)@b@ {@b@ int outBuff;@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@ try@b@ {@b@ 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@ } catch (Exception e) {@b@ LOGGER.log(Level.SEVERE, e.getMessage(), e);@b@ LOGGER.severe("" + source[srcOffset] + ": " + DECODABET[source[srcOffset]]);@b@ LOGGER.severe("" + source[(srcOffset + 1)] + ": " + DECODABET[source[(srcOffset + 1)]]);@b@ LOGGER.severe("" + source[(srcOffset + 2)] + ": " + DECODABET[source[(srcOffset + 2)]]);@b@ LOGGER.severe("" + source[(srcOffset + 3)] + ": " + DECODABET[source[(srcOffset + 3)]]); }@b@ return -1;@b@ }@b@@b@ public static byte[] decode(byte[] source, int off, int len, int options)@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 sbiCrop = 0;@b@ byte sbiDecode = 0;@b@ for (i = off; i < off + len; ++i)@b@ {@b@ sbiCrop = (byte)(source[i] & 0x7F);@b@ sbiDecode = DECODABET[sbiCrop];@b@@b@ if (sbiDecode >= -5)@b@ {@b@ if (sbiDecode < -1)@b@ break label170;@b@ b4[(b4Posn++)] = sbiCrop;@b@ if (b4Posn <= 3)@b@ break label170;@b@ outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options);@b@ b4Posn = 0;@b@@b@ if (sbiCrop != 61) break label170;@b@ break;@b@ }@b@@b@ LOGGER.warning("Bad Base64 input character at " + i + ": " + source[i] + "(decimal)");@b@ return null;@b@ }@b@@b@ label170: 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@ {@b@ return decode(s, 0);@b@ }@b@@b@ public static byte[] decode(String s, int options)@b@ {@b@ try@b@ {@b@ bytes = s.getBytes("UTF-8");@b@ }@b@ catch (UnsupportedEncodingException uee)@b@ {@b@ bytes = s.getBytes(Charset.defaultCharset());@b@ }@b@@b@ byte[] bytes = decode(bytes, 0, bytes.length, options);@b@@b@ if ((bytes != null) && (bytes.length >= 4))@b@ {@b@ int head = bytes[0] & 0xFF | bytes[1] << 8 & 0xFF00;@b@ if (35615 == head)@b@ {@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@ {@b@ baos.write(buffer, 0, length);@b@ }@b@@b@ bytes = baos.toByteArray();@b@ }@b@ catch (IOException localException6)@b@ {@b@ }@b@ finally@b@ {@b@ try@b@ {@b@ baos.close(); } catch (Exception localException7) { }@b@ try { gzis.close(); } catch (Exception localException8) { }@b@ try { bais.close();@b@ } catch (Exception localException9) {@b@ }@b@ }@b@ }@b@ }@b@ return bytes;@b@ }@b@@b@ public static Object decodeToObject(String encodedObject)@b@ {@b@ byte[] objBytes = decode(encodedObject);@b@@b@ ByteArrayInputStream bais = null;@b@ ObjectInputStream ois = null;@b@ Object obj = null;@b@ try@b@ {@b@ bais = new ByteArrayInputStream(objBytes);@b@ ois = new ObjectInputStream(bais);@b@@b@ obj = ois.readObject();@b@ }@b@ catch (IOException e)@b@ {@b@ LOGGER.log(Level.SEVERE, "Error reading object", e);@b@ }@b@ catch (ClassNotFoundException e)@b@ {@b@ LOGGER.log(Level.SEVERE, "Class not found for encoded object", e);@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 boolean encodeToFile(byte[] dataToEncode, String filename)@b@ {@b@ boolean success = false;@b@ OutputStream bos = null;@b@ try@b@ {@b@ bos = new OutputStream(new FileOutputStream(filename), 1);@b@@b@ bos.write(dataToEncode);@b@ success = true;@b@ }@b@ catch (IOException e)@b@ {@b@ success = false;@b@ }@b@ finally {@b@ try {@b@ bos.close(); } catch (Exception localException2) {@b@ }@b@ }@b@ return success;@b@ }@b@@b@ public static boolean decodeToFile(String dataToDecode, String filename)@b@ {@b@ boolean success = false;@b@ OutputStream bos = null;@b@ try@b@ {@b@ bos = new OutputStream(new FileOutputStream(filename), 0);@b@@b@ bos.write(dataToDecode.getBytes("UTF-8"));@b@ success = true;@b@ }@b@ catch (IOException e)@b@ {@b@ success = false;@b@ }@b@ finally {@b@ try {@b@ bos.close(); } catch (Exception localException2) {@b@ }@b@ }@b@ return success;@b@ }@b@@b@ public static byte[] decodeFromFile(String filename)@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@ LOGGER.warning("File is too big for this convenience method (" + file.length() + " bytes).");@b@ Object localObject1 = null;@b@@b@ return localObject1;@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@ LOGGER.log(Level.SEVERE, "Error decoding from file " + filename, e);@b@ }@b@ finally {@b@ try {@b@ bis.close(); } catch (Exception localException2) {@b@ }@b@ }@b@ return decodedData;@b@ }@b@@b@ public static String encodeFromFile(String filename)@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), 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, "UTF-8");@b@ }@b@ catch (IOException e)@b@ {@b@ LOGGER.log(Level.SEVERE, "Error encoding from file " + filename, e);@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@ {@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 ex) {@b@ LOGGER.log(Level.SEVERE, "Error encoding file " + infile, ex);@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@ {@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 ex) {@b@ LOGGER.log(Level.SEVERE, "Error decoding file " + infile, ex);@b@ } finally {@b@ try {@b@ out.close();@b@ }@b@ catch (Exception localException2)@b@ {@b@ }@b@ }@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) != 8);@b@ this.encode = ((options & 0x1) == 1);@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@ {@b@ this.out.write(theByte);@b@ return;@b@ }@b@@b@ if (this.encode)@b@ {@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@ {@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@ {@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@@b@ this.position = 0;@b@ }@b@ }@b@ else if (this.decodabet[(theByte & 0x7F)] != -5)@b@ {@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@ {@b@ this.out.write(theBytes, off, len);@b@ return;@b@ }@b@@b@ for (int i = 0; i < len; ++i)@b@ {@b@ write(theBytes[(off + i)]);@b@ }@b@ }@b@@b@ public void flushBase64()@b@ throws IOException@b@ {@b@ if (this.position > 0)@b@ {@b@ if (this.encode)@b@ {@b@ this.out.write(Base64.access$300(this.b4, this.buffer, this.position, this.options));@b@ this.position = 0;@b@ }@b@ else@b@ {@b@ throw new IOException("Base64 input not properly padded.");@b@ }@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.breakLines = ((options & 0x8) != 8);@b@ this.encode = ((options & 0x1) == 1);@b@ this.bufferLength = ((this.encode) ? 4 : 3);@b@ this.buffer = new byte[this.bufferLength];@b@ this.position = -1;@b@ this.lineLength = 0;@b@ this.options = options;@b@ this.decodabet = Base64.access$000(options);@b@ }@b@@b@ public int read()@b@ throws IOException@b@ {@b@ if (this.position < 0)@b@ {@b@ if (this.encode)@b@ {@b@ byte[] b3 = new byte[3];@b@ int numBinaryBytes = 0;@b@ for (int i = 0; i < 3; ++i)@b@ {@b@ try@b@ {@b@ int b = this.in.read();@b@@b@ if (b >= 0)@b@ {@b@ b3[i] = (byte)b;@b@ ++numBinaryBytes;@b@ }@b@@b@ }@b@ catch (IOException e)@b@ {@b@ if (i == 0)@b@ throw e;@b@ }@b@@b@ }@b@@b@ if (numBinaryBytes > 0)@b@ {@b@ Base64.access$100(b3, 0, numBinaryBytes, this.buffer, 0, this.options);@b@ this.position = 0;@b@ this.numSigBytes = 4;@b@ }@b@ else@b@ {@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@ b4[i] = (byte)b;@b@ }@b@@b@ if (i == 4)@b@ {@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@ if ((this.encode) && (this.breakLines) && (this.lineLength >= 76))@b@ {@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@ 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@ {@b@ int b = read();@b@@b@ if (b >= 0) {@b@ dest[(off + i)] = (byte)b; } else {@b@ if (i != 0) break;@b@ return -1;@b@ }@b@ }@b@@b@ return i;@b@ }@b@ }@b@}
2.Java7Base64Encoder类
package org.jivesoftware.smack.util.stringencoder.java7;@b@@b@import java.io.UnsupportedEncodingException;@b@import org.jivesoftware.smack.util.stringencoder.Base64.Encoder;@b@@b@public final class Java7Base64Encoder@b@ implements Base64.Encoder@b@{@b@ private static final Java7Base64Encoder instance = new Java7Base64Encoder();@b@ private static final int BASE64_ENCODER_FLAGS = 8;@b@@b@ public static Java7Base64Encoder getInstance()@b@ {@b@ return instance;@b@ }@b@@b@ public byte[] decode(String string)@b@ {@b@ return Base64.decode(string);@b@ }@b@@b@ public byte[] decode(byte[] input, int offset, int len)@b@ {@b@ return Base64.decode(input, offset, len, 0);@b@ }@b@@b@ public String encodeToString(byte[] input, int offset, int len)@b@ {@b@ return Base64.encodeBytes(input, offset, len, 8);@b@ }@b@@b@ public byte[] encode(byte[] input, int offset, int len)@b@ {@b@ String string = encodeToString(input, offset, len);@b@ try {@b@ return string.getBytes("US-ASCII");@b@ } catch (UnsupportedEncodingException e) {@b@ throw new AssertionError(e);@b@ }@b@ }@b@}
3.Java7Base64UrlSafeEncoder类
package org.jivesoftware.smack.util.stringencoder.java7;@b@@b@import java.io.UnsupportedEncodingException;@b@import org.jivesoftware.smack.util.stringencoder.StringEncoder;@b@@b@public final class Java7Base64UrlSafeEncoder@b@ implements StringEncoder@b@{@b@ private static final Java7Base64UrlSafeEncoder instance = new Java7Base64UrlSafeEncoder();@b@ private static final int BASE64_ENCODER_FLAGS = 24;@b@@b@ public static Java7Base64UrlSafeEncoder getInstance()@b@ {@b@ return instance;@b@ }@b@@b@ public String encode(String s)@b@ {@b@ byte[] bytes;@b@ try {@b@ bytes = s.getBytes("UTF-8");@b@ }@b@ catch (UnsupportedEncodingException e) {@b@ throw new AssertionError(e);@b@ }@b@ return Base64.encodeBytes(bytes, 24);@b@ }@b@@b@ public String decode(String s)@b@ {@b@ try {@b@ return new String(Base64.decode(s, 24), "UTF-8");@b@ }@b@ catch (UnsupportedEncodingException e) {@b@ throw new AssertionError(e);@b@ }@b@ }@b@}