import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.zip.Deflater; import java.util.zip.Inflater;
public class Base64 {
/** * Byte value that maps to 'a' in Base64 encoding */ private final static int LOWER_CASE_A_VALUE = 26;
/** * Byte value that maps to '0' in Base64 encoding */ private final static int ZERO_VALUE = 52;
/** * Byte value that maps to '+' in Base64 encoding */ private final static int PLUS_VALUE = 62;
/** * Byte value that maps to '/' in Base64 encoding */ private final static int SLASH_VALUE = 63;
/** * Bit mask for one character worth of bits in Base64 encoding. Equivalent * to binary value 111111b. */ private final static int SIX_BIT_MASK = 63;
/** * Bit mask for one byte worth of bits in Base64 encoding. Equivalent to * binary value 11111111b. */ private static final int EIGHT_BIT_MASK = 0xFF;
/** * The input String to be decoded */ private String mString;
/** * Current position in the String(to be decoded) */ private int mIndex = 0;
/** * Encode an array of bytes using Base64 * * @param data[] * The bytes to be encoded * @return A valid Base64 representation of the input */ public static String encode(byte data[]) { return new Base64().internalEncode(data); }
/** * Encode an array of bytes using Base64 * * @param data[] * The bytes to be encoded * @return A valid Base64 representation of the input */ public String internalEncode(byte data[]) { // Base64 encoding yields a String that is 33% longer than the byte // array int charCount = ((data.length * 4) / 3) + 4;
// New lines will also be needed for every 76 charactesr, so allocate a // StringBuffer that is long enough to hold the full result without // having to expand later StringBuffer result = new StringBuffer((charCount * 77) / 76);
int byteArrayLength = data.length; int byteArrayIndex = 0; int byteTriplet = 0; while (byteArrayIndex < byteArrayLength - 2) { // Build the 24 bit byte triplet from the input data byteTriplet = convertUnsignedByteToInt(data[byteArrayIndex++]); // Each input byte contributes 8 bits to the triplet byteTriplet <<= 8; byteTriplet |= convertUnsignedByteToInt(data[byteArrayIndex++]); byteTriplet <<= 8; byteTriplet |= convertUnsignedByteToInt(data[byteArrayIndex++]);
// Look at the lowest order six bits and remember them byte b4 = (byte) (SIX_BIT_MASK & byteTriplet); // Move the byte triplet to get the next 6 bit value byteTriplet >>= 6; byte b3 = (byte) (SIX_BIT_MASK & byteTriplet); byteTriplet >>= 6; byte b2 = (byte) (SIX_BIT_MASK & byteTriplet); byteTriplet >>= 6; byte b1 = (byte) (SIX_BIT_MASK & byteTriplet);
// Add the Base64 encoded character to the result String result.append(mapByteToChar(b1)); result.append(mapByteToChar(b2)); result.append(mapByteToChar(b3)); result.append(mapByteToChar(b4));
// There are 57 bytes for every 76 characters, so wrap the line when // needed // if ( byteArrayIndex % 57 == 0 ) { // result.append( "\n" ); // } }
// Check if we have one byte left over if (byteArrayIndex == byteArrayLength - 1) { // Convert our one byte to an int byteTriplet = convertUnsignedByteToInt(data[byteArrayIndex++]); // Right pad the second 6 bit value with zeros byteTriplet <<= 4;
byte b2 = (byte) (SIX_BIT_MASK & byteTriplet); byteTriplet >>= 6; byte b1 = (byte) (SIX_BIT_MASK & byteTriplet);
result.append(mapByteToChar(b1)); result.append(mapByteToChar(b2));
// Add "==" to the output to make it a multiple of 4 Base64 // characters result.append("=="); }
// Check if we have two byte left over if (byteArrayIndex == byteArrayLength - 2) { // Convert our two bytes to an int byteTriplet = convertUnsignedByteToInt(data[byteArrayIndex++]); byteTriplet <<= 8; byteTriplet |= convertUnsignedByteToInt(data[byteArrayIndex++]); // Right pad the third 6 bit value with zeros byteTriplet <<= 2;
byte b3 = (byte) (SIX_BIT_MASK & byteTriplet); byteTriplet >>= 6; byte b2 = (byte) (SIX_BIT_MASK & byteTriplet); byteTriplet >>= 6; byte b1 = (byte) (SIX_BIT_MASK & byteTriplet);
result.append(mapByteToChar(b1)); result.append(mapByteToChar(b2)); result.append(mapByteToChar(b3));
// Add "==" to the output to make it a multiple of 4 Base64 // characters result.append("="); }
return result.toString(); }
/** * Decode an input String using Base64 * * @param data * The String to be decoded * @return The appropriate byte array */ public static byte[] decode(String data) { return new Base64().internalDecode(data); }
/** * Decode an input String using Base64 * * @param data * The String to be decoded * @return The appropriate byte array */ public byte[] internalDecode(String data) { mString = data; mIndex = 0;
/** * Total number of Base64 characters in the input */ int mUsefulLength = 0; int length = mString.length(); for (int i = 0; i < length; i++) { if (isUsefulChar(mString.charAt(i))) { mUsefulLength++; } }
// mString = data;
// A Base64 byte array is 75% the size of its String representation int byteArrayLength = mUsefulLength * 3 / 4;
byte result[] = new byte[byteArrayLength];
int byteTriplet = 0; int byteIndex = 0;
// Continue until we have less than 4 full characters left to // decode in the input. while (byteIndex + 2 < byteArrayLength) {
// Package a set of four characters into a byte triplet // Each character contributes 6 bits of useful information byteTriplet = mapCharToInt(getNextUsefulChar()); byteTriplet <<= 6; byteTriplet |= mapCharToInt(getNextUsefulChar()); byteTriplet <<= 6; byteTriplet |= mapCharToInt(getNextUsefulChar()); byteTriplet <<= 6; byteTriplet |= mapCharToInt(getNextUsefulChar());
// Grab a normal byte (eight bits) out of the byte triplet // and put it in the byte array result[byteIndex + 2] = (byte) (byteTriplet & EIGHT_BIT_MASK); byteTriplet >>= 8; result[byteIndex + 1] = (byte) (byteTriplet & EIGHT_BIT_MASK); byteTriplet >>= 8; result[byteIndex] = (byte) (byteTriplet & EIGHT_BIT_MASK); byteIndex += 3; }
// Check if we have one byte left to decode if (byteIndex == byteArrayLength - 1) { // Take out the last two characters from the String byteTriplet = mapCharToInt(getNextUsefulChar()); byteTriplet <<= 6; byteTriplet |= mapCharToInt(getNextUsefulChar());
// Remove the padded zeros byteTriplet >>= 4; result[byteIndex] = (byte) (byteTriplet & EIGHT_BIT_MASK); }
// Check if we have two bytes left to decode if (byteIndex == byteArrayLength - 2) { // Take out the last three characters from the String byteTriplet = mapCharToInt(getNextUsefulChar()); byteTriplet <<= 6; byteTriplet |= mapCharToInt(getNextUsefulChar()); byteTriplet <<= 6; byteTriplet |= mapCharToInt(getNextUsefulChar());
// Remove the padded zeros byteTriplet >>= 2; result[byteIndex + 1] = (byte) (byteTriplet & EIGHT_BIT_MASK); byteTriplet >>= 8; result[byteIndex] = (byte) (byteTriplet & EIGHT_BIT_MASK); }
return result; }
/** * Convert a Base64 character to its 6 bit value as defined by the mapping. * * @param c * Base64 character to decode * @return int representation of 6 bit value */ private int mapCharToInt(char c) { if (c >= 'A' && c <= 'Z') { return c - 'A'; }
if (c >= 'a' && c <= 'z') { return (c - 'a') + LOWER_CASE_A_VALUE; }
if (c >= '0' && c <= '9') { return (c - '0') + ZERO_VALUE; }
if (c == '+') { return PLUS_VALUE; }
if (c == '/') { return SLASH_VALUE; }
throw new IllegalArgumentException(c + " is not a valid Base64 character."); }
/** * Convert a byte between 0 and 63 to its Base64 character equivalent * * @param b * Byte value to be converted * @return Base64 char value */ private char mapByteToChar(byte b) { if (b < LOWER_CASE_A_VALUE) { return (char) ('A' + b); }
if (b < ZERO_VALUE) { return (char) ('a' + (b - LOWER_CASE_A_VALUE)); }
if (b < PLUS_VALUE) { return (char) ('0' + (b - ZERO_VALUE)); }
if (b == PLUS_VALUE) { return '+'; }
if (b == SLASH_VALUE) { return '/'; }
throw new IllegalArgumentException("Byte " + new Integer(b) + " is not a valid Base64 value"); }
/** * @param c * Character to be examined * @return Whether or not the character is a Base64 character */ private boolean isUsefulChar(char c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == '/'); }
/** * Traverse the String until hitting the next Base64 character. Assumes that * there is still another valid Base64 character left in the String. */ private char getNextUsefulChar() { char result = '_'; // Start with a non-Base64 character while (!isUsefulChar(result)) { result = mString.charAt(mIndex++); }
return result; }
/** * Convert a byte to an integer. Needed because in Java bytes are signed, * and for Base64 purposes they are not. If not done this way, when * converted to an int, 0xFF will become -127 * * @param b * Byte value to be converted * @return Value as an integer, as if byte was unsigned */ private int convertUnsignedByteToInt(byte b) { if (b >= 0) { return (int) b; }
return 256 + b; }
public static String getEncodeMsg(String tMessage) { String returnStr = ""; try { ByteArrayOutputStream byteStream = getCompressedStr(tMessage);
if(byteStream!=null) returnStr = Base64.encode(byteStream.toByteArray());
//returnStr = Base64.encode(tMessage.getBytes("UTF-8"));
} catch (Exception ex) {
ex.printStackTrace(); }
return returnStr; }
private static ByteArrayOutputStream getCompressedStr(String tMessage) {
ByteArrayOutputStream compressedStream = null; try { if (tMessage != null && !"".equals(tMessage)) {
byte[] input = tMessage.getBytes("UTF-8");
Deflater compresser = new Deflater(); compresser.setInput(input); compresser.finish();
compressedStream = new ByteArrayOutputStream(); byte[] buf = new byte[2048];
while (!compresser.finished()) { int got = compresser.deflate(buf); compressedStream.write(buf, 0, got); } }
} catch (Exception ex) {
ex.printStackTrace(); } finally { if (compressedStream != null) { try { compressedStream.close(); } catch (IOException ioex) {
ioex.printStackTrace(); } }
}
return compressedStream;
}
public static String getDecodeMsg(String tMessage) { String outputString = ""; byte[] inputStr = null; try { String newStr = tMessage; newStr = newStr.replaceAll(" ", "+"); inputStr = Base64.decode(newStr); outputString = getDeCompressedStr(inputStr);
} catch (Exception ex) {
ex.printStackTrace(); }
return outputString;
// return new String(inputStr); }
private static String getDeCompressedStr(byte[] tMessage) { String returnStr = ""; ByteArrayOutputStream aDeCompressedStream = null; try {
// Decompress the bytes Inflater decompresser = new Inflater();
decompresser.setInput(tMessage);
aDeCompressedStream = new ByteArrayOutputStream();
byte[] buf = new byte[2048]; while (!decompresser.finished()) { int got = decompresser.inflate(buf); aDeCompressedStream.write(buf, 0, got); }
} catch (Exception ex) {
ex.printStackTrace(); } finally { try { if(aDeCompressedStream!=null) aDeCompressedStream.close(); } catch (IOException ioex) {
ioex.printStackTrace(); } }
try { returnStr = aDeCompressedStream.toString("UTF-8");
} catch (UnsupportedEncodingException encodeEx) {
encodeEx.printStackTrace(); }
return returnStr; }
} |
转载于:https://www.cnblogs.com/chinaifae/p/10400520.html