public final class Base64
{
/** Base64编码表。*/
private static char[] base64Code =
{
'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', '+', '/',
};
/** Base64解码表。*/
private static byte[] base64Decode =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1, //注意两个63,为兼容SMP,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
NumberConstants.BYTE_62,
-1,
NumberConstants.BYTE_63,
-1,
NumberConstants.BYTE_63, //“/”和“-”都翻译成63。
NumberConstants.BYTE_52, NumberConstants.BYTE_53, NumberConstants.BYTE_54,
NumberConstants.BYTE_55, NumberConstants.BYTE_56, NumberConstants.BYTE_57,
NumberConstants.BYTE_58, NumberConstants.BYTE_59, NumberConstants.BYTE_60,
NumberConstants.BYTE_61, -1, -1, -1, 0, -1, -1, -1,
0,
NumberConstants.BYTE_1,
NumberConstants.BYTE_2,
NumberConstants.BYTE_3,
NumberConstants.BYTE_4,
NumberConstants.BYTE_5,
NumberConstants.BYTE_6,
NumberConstants.BYTE_7,
NumberConstants.BYTE_8,
NumberConstants.BYTE_9,
NumberConstants.BYTE_10,
NumberConstants.BYTE_11,
NumberConstants.BYTE_12,
NumberConstants.BYTE_13,
NumberConstants.BYTE_14, //注意两个0:
NumberConstants.BYTE_15, NumberConstants.BYTE_16, NumberConstants.BYTE_17,
NumberConstants.BYTE_18, NumberConstants.BYTE_19, NumberConstants.BYTE_20,
NumberConstants.BYTE_21,
NumberConstants.BYTE_22,
NumberConstants.BYTE_23,
NumberConstants.BYTE_24,
NumberConstants.BYTE_25,
-1,
-1,
-1,
-1,
-1, //“A”和“=”都翻译成0。
-1, NumberConstants.BYTE_26, NumberConstants.BYTE_27, NumberConstants.BYTE_28,
NumberConstants.BYTE_29, NumberConstants.BYTE_30, NumberConstants.BYTE_31,
NumberConstants.BYTE_32, NumberConstants.BYTE_33, NumberConstants.BYTE_34,
NumberConstants.BYTE_35, NumberConstants.BYTE_36, NumberConstants.BYTE_37,
NumberConstants.BYTE_38, NumberConstants.BYTE_39, NumberConstants.BYTE_40,
NumberConstants.BYTE_41, NumberConstants.BYTE_42, NumberConstants.BYTE_43,
NumberConstants.BYTE_44, NumberConstants.BYTE_45, NumberConstants.BYTE_46,
NumberConstants.BYTE_47, NumberConstants.BYTE_48, NumberConstants.BYTE_49,
NumberConstants.BYTE_50, NumberConstants.BYTE_51, -1, -1, -1, -1, -1,
};
/**
* 构造方法私有化,防止实例化。
*/
private Base64()
{
}
/**
* Base64编码。将字节数组中字节3个一组编码成4个可见字符。
*
* @param b 需要被编码的字节数据。
* @return 编码后的Base64字符串。
*/
public static String encode(byte[] b)
{
int code = 0;
//按实际编码后长度开辟内存,加快速度
StringBuffer sb =
new StringBuffer(((b.length - 1) / NumberConstants.NUM_3) << NumberConstants.NUM_2
+ NumberConstants.NUM_4);
//进行编码
for (int i = 0; i < b.length; i++)
{
code |=
(b[i] << (NumberConstants.NUM_16 - i % NumberConstants.NUM_3 * NumberConstants.NUM_8))
& (NumberConstants.NUM_0XFF << (NumberConstants.NUM_16 - i % NumberConstants.NUM_3
* NumberConstants.NUM_8));
if (i % NumberConstants.NUM_3 == NumberConstants.NUM_2 || i == b.length - 1)
{
sb.append(base64Code[(code & NumberConstants.NUM_0XFC0000) >>> NumberConstants.NUM_18]);
sb.append(base64Code[(code & NumberConstants.NUM_0X3F000) >>> NumberConstants.NUM_12]);
sb.append(base64Code[(code & NumberConstants.NUM_0XFC0) >>> NumberConstants.NUM_6]);
sb.append(base64Code[code & NumberConstants.NUM_0X3F]);
code = 0;
}
}
//对于长度非3的整数倍的字节数组,编码前先补0,编码后结尾处编码用=代替,
//=的个数和短缺的长度一致,以此来标识出数据实际长度
if (b.length % NumberConstants.NUM_3 > 0)
{
sb.setCharAt(sb.length() - 1, '=');
}
if (b.length % NumberConstants.NUM_3 == 1)
{
sb.setCharAt(sb.length() - NumberConstants.NUM_2, '=');
}
return sb.toString();
}
/**
* Base64解码。
*
* @param code 用Base64编码的ASCII字符串
* @return 解码后的字节数据
*/
public static byte[] decode(String code)
{
//检查参数合法性
if (code == null)
{
return null;
}
int len = code.length();
if (len % NumberConstants.NUM_4 != 0)
{
throw new IllegalArgumentException("Base64 string length must be 4*n");
}
if (code.length() == 0)
{
return new byte[0];
}
//统计填充的等号个数
int pad = 0;
if (code.charAt(len - 1) == '=')
{
pad++;
}
if (code.charAt(len - NumberConstants.NUM_2) == '=')
{
pad++;
}
//根据填充等号的个数来计算实际数据长度
int retLen = len / NumberConstants.NUM_4 * NumberConstants.NUM_3 - pad;
//分配字节数组空间
byte[] ret = new byte[retLen];
//查表解码
char ch1, ch2, ch3, ch4;
int i;
for (i = 0; i < len; i += NumberConstants.BYTE_4)
{
int j = i / NumberConstants.NUM_4 * NumberConstants.NUM_3;
ch1 = code.charAt(i);
ch2 = code.charAt(i + 1);
ch3 = code.charAt(i + NumberConstants.NUM_2);
ch4 = code.charAt(i + NumberConstants.NUM_3);
int tmp =
(base64Decode[ch1] << NumberConstants.NUM_18) | (base64Decode[ch2] << NumberConstants.NUM_12)
| (base64Decode[ch3] << NumberConstants.BYTE_6) | (base64Decode[ch4]);
ret[j] = (byte)((tmp & NumberConstants.NUM_0XFF0000) >> NumberConstants.NUM_16);
if (i < len - NumberConstants.NUM_4)
{
ret[j + NumberConstants.NUM_1] =
(byte)((tmp & NumberConstants.NUM_0X00FF00) >> NumberConstants.NUM_8);
ret[j + NumberConstants.NUM_2] = (byte)((tmp & NumberConstants.NUM_0X0000FF));
}
else
{
if (j + 1 < retLen)
{
ret[j + 1] = (byte)((tmp & NumberConstants.NUM_0X00FF00) >> NumberConstants.NUM_8);
}
if (j + NumberConstants.NUM_2 < retLen)
{
ret[j + NumberConstants.NUM_2] = (byte)((tmp & NumberConstants.NUM_0X0000FF));
}
}
}
return ret;
}
}
{
/** Base64编码表。*/
private static char[] base64Code =
{
'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', '+', '/',
};
/** Base64解码表。*/
private static byte[] base64Decode =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1, //注意两个63,为兼容SMP,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
NumberConstants.BYTE_62,
-1,
NumberConstants.BYTE_63,
-1,
NumberConstants.BYTE_63, //“/”和“-”都翻译成63。
NumberConstants.BYTE_52, NumberConstants.BYTE_53, NumberConstants.BYTE_54,
NumberConstants.BYTE_55, NumberConstants.BYTE_56, NumberConstants.BYTE_57,
NumberConstants.BYTE_58, NumberConstants.BYTE_59, NumberConstants.BYTE_60,
NumberConstants.BYTE_61, -1, -1, -1, 0, -1, -1, -1,
0,
NumberConstants.BYTE_1,
NumberConstants.BYTE_2,
NumberConstants.BYTE_3,
NumberConstants.BYTE_4,
NumberConstants.BYTE_5,
NumberConstants.BYTE_6,
NumberConstants.BYTE_7,
NumberConstants.BYTE_8,
NumberConstants.BYTE_9,
NumberConstants.BYTE_10,
NumberConstants.BYTE_11,
NumberConstants.BYTE_12,
NumberConstants.BYTE_13,
NumberConstants.BYTE_14, //注意两个0:
NumberConstants.BYTE_15, NumberConstants.BYTE_16, NumberConstants.BYTE_17,
NumberConstants.BYTE_18, NumberConstants.BYTE_19, NumberConstants.BYTE_20,
NumberConstants.BYTE_21,
NumberConstants.BYTE_22,
NumberConstants.BYTE_23,
NumberConstants.BYTE_24,
NumberConstants.BYTE_25,
-1,
-1,
-1,
-1,
-1, //“A”和“=”都翻译成0。
-1, NumberConstants.BYTE_26, NumberConstants.BYTE_27, NumberConstants.BYTE_28,
NumberConstants.BYTE_29, NumberConstants.BYTE_30, NumberConstants.BYTE_31,
NumberConstants.BYTE_32, NumberConstants.BYTE_33, NumberConstants.BYTE_34,
NumberConstants.BYTE_35, NumberConstants.BYTE_36, NumberConstants.BYTE_37,
NumberConstants.BYTE_38, NumberConstants.BYTE_39, NumberConstants.BYTE_40,
NumberConstants.BYTE_41, NumberConstants.BYTE_42, NumberConstants.BYTE_43,
NumberConstants.BYTE_44, NumberConstants.BYTE_45, NumberConstants.BYTE_46,
NumberConstants.BYTE_47, NumberConstants.BYTE_48, NumberConstants.BYTE_49,
NumberConstants.BYTE_50, NumberConstants.BYTE_51, -1, -1, -1, -1, -1,
};
/**
* 构造方法私有化,防止实例化。
*/
private Base64()
{
}
/**
* Base64编码。将字节数组中字节3个一组编码成4个可见字符。
*
* @param b 需要被编码的字节数据。
* @return 编码后的Base64字符串。
*/
public static String encode(byte[] b)
{
int code = 0;
//按实际编码后长度开辟内存,加快速度
StringBuffer sb =
new StringBuffer(((b.length - 1) / NumberConstants.NUM_3) << NumberConstants.NUM_2
+ NumberConstants.NUM_4);
//进行编码
for (int i = 0; i < b.length; i++)
{
code |=
(b[i] << (NumberConstants.NUM_16 - i % NumberConstants.NUM_3 * NumberConstants.NUM_8))
& (NumberConstants.NUM_0XFF << (NumberConstants.NUM_16 - i % NumberConstants.NUM_3
* NumberConstants.NUM_8));
if (i % NumberConstants.NUM_3 == NumberConstants.NUM_2 || i == b.length - 1)
{
sb.append(base64Code[(code & NumberConstants.NUM_0XFC0000) >>> NumberConstants.NUM_18]);
sb.append(base64Code[(code & NumberConstants.NUM_0X3F000) >>> NumberConstants.NUM_12]);
sb.append(base64Code[(code & NumberConstants.NUM_0XFC0) >>> NumberConstants.NUM_6]);
sb.append(base64Code[code & NumberConstants.NUM_0X3F]);
code = 0;
}
}
//对于长度非3的整数倍的字节数组,编码前先补0,编码后结尾处编码用=代替,
//=的个数和短缺的长度一致,以此来标识出数据实际长度
if (b.length % NumberConstants.NUM_3 > 0)
{
sb.setCharAt(sb.length() - 1, '=');
}
if (b.length % NumberConstants.NUM_3 == 1)
{
sb.setCharAt(sb.length() - NumberConstants.NUM_2, '=');
}
return sb.toString();
}
/**
* Base64解码。
*
* @param code 用Base64编码的ASCII字符串
* @return 解码后的字节数据
*/
public static byte[] decode(String code)
{
//检查参数合法性
if (code == null)
{
return null;
}
int len = code.length();
if (len % NumberConstants.NUM_4 != 0)
{
throw new IllegalArgumentException("Base64 string length must be 4*n");
}
if (code.length() == 0)
{
return new byte[0];
}
//统计填充的等号个数
int pad = 0;
if (code.charAt(len - 1) == '=')
{
pad++;
}
if (code.charAt(len - NumberConstants.NUM_2) == '=')
{
pad++;
}
//根据填充等号的个数来计算实际数据长度
int retLen = len / NumberConstants.NUM_4 * NumberConstants.NUM_3 - pad;
//分配字节数组空间
byte[] ret = new byte[retLen];
//查表解码
char ch1, ch2, ch3, ch4;
int i;
for (i = 0; i < len; i += NumberConstants.BYTE_4)
{
int j = i / NumberConstants.NUM_4 * NumberConstants.NUM_3;
ch1 = code.charAt(i);
ch2 = code.charAt(i + 1);
ch3 = code.charAt(i + NumberConstants.NUM_2);
ch4 = code.charAt(i + NumberConstants.NUM_3);
int tmp =
(base64Decode[ch1] << NumberConstants.NUM_18) | (base64Decode[ch2] << NumberConstants.NUM_12)
| (base64Decode[ch3] << NumberConstants.BYTE_6) | (base64Decode[ch4]);
ret[j] = (byte)((tmp & NumberConstants.NUM_0XFF0000) >> NumberConstants.NUM_16);
if (i < len - NumberConstants.NUM_4)
{
ret[j + NumberConstants.NUM_1] =
(byte)((tmp & NumberConstants.NUM_0X00FF00) >> NumberConstants.NUM_8);
ret[j + NumberConstants.NUM_2] = (byte)((tmp & NumberConstants.NUM_0X0000FF));
}
else
{
if (j + 1 < retLen)
{
ret[j + 1] = (byte)((tmp & NumberConstants.NUM_0X00FF00) >> NumberConstants.NUM_8);
}
if (j + NumberConstants.NUM_2 < retLen)
{
ret[j + NumberConstants.NUM_2] = (byte)((tmp & NumberConstants.NUM_0X0000FF));
}
}
}
return ret;
}
}