package base64;
import java.util.Arrays;
import java.util.Hashtable;
public class Base64 {
private static char[] baseChar =
{
'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',
'+','/'
};
private static Hashtable<Character, Integer> indexs = new Hashtable<Character, Integer>();
static{
indexs.put('A', 0);
indexs.put('B', 1);
indexs.put('C', 2);
indexs.put('D', 3);
indexs.put('E', 4);
indexs.put('F', 5);
indexs.put('G', 6);
indexs.put('H', 7);
indexs.put('I', 8);
indexs.put('J', 9);
indexs.put('K', 10);
indexs.put('L', 11);
indexs.put('M', 12);
indexs.put('N', 13);
indexs.put('O', 14);
indexs.put('P', 15);
indexs.put('Q', 16);
indexs.put('R', 17);
indexs.put('S', 18);
indexs.put('T', 19);
indexs.put('U', 20);
indexs.put('V', 21);
indexs.put('W', 22);
indexs.put('X', 23);
indexs.put('Y', 24);
indexs.put('Z', 25);
indexs.put('a', 26);
indexs.put('b', 27);
indexs.put('c', 28);
indexs.put('d', 29);
indexs.put('e', 30);
indexs.put('f', 31);
indexs.put('g', 32);
indexs.put('h', 33);
indexs.put('i', 34);
indexs.put('j', 35);
indexs.put('k', 36);
indexs.put('l', 37);
indexs.put('m', 38);
indexs.put('n', 39);
indexs.put('o', 40);
indexs.put('p', 41);
indexs.put('q', 42);
indexs.put('r', 43);
indexs.put('s', 44);
indexs.put('t', 45);
indexs.put('u', 46);
indexs.put('v', 47);
indexs.put('w', 48);
indexs.put('x', 49);
indexs.put('y', 50);
indexs.put('z', 51);
indexs.put('0', 52);
indexs.put('1', 53);
indexs.put('2', 54);
indexs.put('3', 55);
indexs.put('4', 56);
indexs.put('5', 57);
indexs.put('6', 58);
indexs.put('7', 59);
indexs.put('8', 60);
indexs.put('9', 61);
indexs.put('+', 62);
indexs.put('/', 63);
indexs.put('=', 0);
}
private static byte getByte(char ch)
{
return (byte)(int)indexs.get(ch);
}
private static byte[] intToByteArray(int a) {
return new byte[] {
(byte) ((a >> 24) & 0xFF),
(byte) ((a >> 16) & 0xFF),
(byte) ((a >> 8) & 0xFF),
(byte) (a & 0xFF)
};
}
//加密算法
public static String from(String source)
{
byte[] bytes = source.getBytes();
int mend = 3 - bytes.length % 3;
//补位
if(mend != 3)
{
byte[] bytesnew = new byte[bytes.length + mend];
System.arraycopy(bytes, 0, bytesnew, 0, bytes.length);
bytes = bytesnew;
}
//
StringBuffer sb = new StringBuffer();
for(int i = 0; i < bytes.length; i += 3)
{
//解析第一位
byte c1 = (byte) ((bytes[i] & 0xff) >> 2);
//解析第二位
byte mask = 3;
byte c2 = (byte) (((mask & bytes[i]) << 4) | ((bytes[i + 1] & 0xff) >> 4));
//解析第三位
byte mask1 = 15;
byte c3 = (byte) (((mask1 & bytes[i + 1]) << 2) | ((bytes[i + 2] & 0xff ) >> 6));
//解析第四位
byte mask2 = 63;
byte c4 = (byte) (mask2 & bytes[i + 2]);
sb.append(baseChar[c1]);
sb.append(baseChar[c2]);
sb.append(baseChar[c3]);
sb.append(baseChar[c4]);
}
String rep = mend == 1 ? "=" : "==";
if(mend != 3)
{
sb.replace(sb.length() - mend, sb.length(), rep);
}
return sb.toString();
}
//解密算法
public static String parse(String code)
{
if(code.length() % 4 == 0)
{
//计算“=”个数
int mend = 0;
int t = code.length();
while(code.charAt(--t) == '=' && t >= 0)
{
mend ++;
}
System.out.println("mend :" + mend);
//解析
int limitL = code.length();
int byteCount = limitL * 3 / 4;
byte[] bytes = new byte[limitL * 3 / 4] ;
for(int i = 0, j = 0; i < limitL; i += 4, j += 3)
{
byte b1 = getByte(code.charAt(i));
byte b2 = getByte(code.charAt(i + 1));
byte b3 = getByte(code.charAt(i + 2));
byte b4 = getByte(code.charAt(i + 3));
int bs = b1 << 18 | b2 << 12 | b3 << 6 | b4;
byte[] bsbytes = intToByteArray(bs);
bytes[j] = bsbytes[1];
bytes[j + 1] = bsbytes[2];
bytes[j + 2] = bsbytes[3];
}
//去掉多余的
return new String(Arrays.copyOfRange(bytes, 0, byteCount - mend));
}
return "";
}
}