package net.proxy;
import java.util.Arrays;
public class BASE64Encoder {
private int uByteToInt(byte b) {
if (b >= 0) {
return (int) b;
}
return 256 + b;
}
public String encode(byte data[]) {
int charCount = ((data.length * 4) / 3) + 4;
StringBuffer result = new StringBuffer(
(charCount * 77) / 76);
int byteArrayLength = data.length;
int byteArrayIndex = 0;
int byteTriplet = 0;
while (byteArrayIndex < byteArrayLength - 2) {
byteArrayIndex = processData(
data, byteArrayIndex, result);
}
byteArrayIndex = checkIfWeHave1ByteLeftOver(
byteArrayIndex, byteArrayLength, data, result);
checkIfWeHaveTwoBytesLeftOver(
byteArrayIndex, byteArrayLength, data, result);
return result.toString();
}
private int processData(
byte[] data, int index,
StringBuffer result) {
int byteTriplet;
byteTriplet = uByteToInt(data[index++]);
byteTriplet <<= 8;
byteTriplet |= uByteToInt(data[index++]);
byteTriplet <<= 8;
byteTriplet |= uByteToInt(data[index++]);
byte b4 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
byteTriplet >>= 6;
byte b3 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
byteTriplet >>= 6;
byte b2 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
byteTriplet >>= 6;
byte b1 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
result.append(byteToChar(b1));
result.append(byteToChar(b2));
result.append(byteToChar(b3));
result.append(byteToChar(b4));
if (index % 57 == 0) {
result.append("\n");
}
return index;
}
private void checkIfWeHaveTwoBytesLeftOver(
int index,
int length,
byte[] byteArray,
StringBuffer sb) {
int byteTriplet;
if (index == length - 2) {
byteTriplet = twoBytesToInt(byteArray, index);
byteTriplet <<= 2;
byte b3 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
byteTriplet >>= 6;
byte b2 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
byteTriplet >>= 6;
byte b1 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
sb.append(byteToChar(b1));
sb.append(byteToChar(b2));
sb.append(byteToChar(b3));
sb.append("=");
}
}
private int checkIfWeHave1ByteLeftOver(
int index,
int length,
byte[] byteArray,
StringBuffer sb) {
int byteTriplet;
if (index == length - 1) {
byteTriplet = uByteToInt(byteArray[index++]);
byteTriplet <<= 4;
byte b2 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
byteTriplet >>= 6;
byte b1 = (byte) (Constants.SIX_BIT_MASK & byteTriplet);
sb.append(byteToChar(b1));
sb.append(byteToChar(b2));
sb.append("==");
}
return index;
}
private int twoBytesToInt(byte[] data, int byteArrayIndex) {
int byteTriplet;
byteTriplet =
uByteToInt(data[byteArrayIndex++]);
byteTriplet <<= 8;
byteTriplet |= uByteToInt(data[byteArrayIndex++]);
return byteTriplet;
}
private char byteToChar(byte b) {
if (b < Constants.LOWER_CASE_A_VALUE) {
return (char) ('A' + b);
}
if (b < Constants.ZERO_VALUE) {
return (char) ('a' + (b - Constants.LOWER_CASE_A_VALUE));
}
if (b < Constants.PLUS_VALUE) {
return (char) ('0' + (b - Constants.ZERO_VALUE));
}
if (b == Constants.PLUS_VALUE) {
return '+';
}
if (b == Constants.SLASH_VALUE) {
return '/';
}
throw
new IllegalArgumentException(
"Byte " +
new Integer(b) +
" is not a valid Base64 value");
}
public static void main(String args[]) throws Exception {
testCodec();
}
private static void testCodec() {
for (int j = 0; j < 100; j++)
test(new BASE64Encoder(), new BASE64Decoder());
}
private static void test(BASE64Encoder encoder, BASE64Decoder decoder) {
byte test[] = new byte[(int) (100000 * Math.random())];
for (int i = 0; i < test.length; i++) {
test[i] = (byte) (256 * Math.random());
}
String string = encoder.encode(test);
byte result[] = decoder.decodeBuffer(string);
if (!Arrays.equals(test, result) || test.length != result.length) {
System.out.println("ARRAYS DO NOT MATCH!");
}
}
}