import java.io.*;
public class Base64Decode {
public static void main
(String[] args
) { // 変換テーブル
char[] table = {
'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', '+', '/'};
try {
char[] cs;
while((cs=read4(in))!=null) {
write3(out, convert6to8(decode(cs, table)));
}
e.printStackTrace(); // 例外の情報を表示する
} finally { // in, out を閉じる
try {
in.close();
out.close();
}
}
}
}
public static int[] decode(char[] cs, char[] table) {
int[] ret = new int[cs.length];
for(int i=0; i<cs.length; i++) {
for(int j=0; j<table.length; j++) {
if(cs[i] == table[j]) {
ret[i] = j;
break;
}
}
}
return ret;
}
public static int[] convert6to8(int[] buf) {
StringBuilder fb = new StringBuilder();
for(int i=0; i<buf.length; i++) {
fb.append(toBinary(buf[i], 6));
}
int[] ret = new int[fb.length()/6-1];
for(int i=0; i<ret.length; i++) {
String f
= fb.
substring(i
*8, i
*8+8); ret[i] = fromBinary(f);
}
return ret;
}
/**
* バイト列 bt の数を順に出力する.
* @param bt 数の配列。長さは 3以下. 各数は8ビットの整数
*/
for (int i=0; i<3; i++) {
if (i<bt.length) {
out.write(bt[i]);
}
}
}
/**
* in から文字を最大4つ読み出す.
* @param in 入力ストリーム
* @return 文字の配列。配列長は最大4. 入力終了したときには null を返す.
*/
char[] bs;
int n0=in.read();
int n1=in.read();
int n2=in.read();
int n3=in.read();
if (n0 < 0) { // 読み込み終了
bs = null;
} else if (n2 < 0 || (char) n2=='=') {
bs = new char[2];
bs[0] = (char) n0;
bs[1] = (char) n1;
} else if (n3 < 0 || (char) n3=='=') {
bs = new char[3];
bs[0] = (char) n0;
bs[1] = (char) n1;
bs[2] = (char) n2;
} else {
bs = new char[4];
bs[0] = (char) n0;
bs[1] = (char) n1;
bs[2] = (char) n2;
bs[3] = (char) n3;
}
return bs;
}
/**
* 数を読み取って、nビットの2進数を表す文字列に変換する
* @param bt 1バイトの数
* @param n 2進数のビット数
* @return 2進数を表す文字列
*/
public static String toBinary
(int bt,
int n
) { for (int i=s.length(); i<n; i++) {
s = "0" + s;
}
return s;
}
/**
* 2進数を表す文字列を数に変換する
* @param b 2進数を表す文字列
* @return b が表す数
*/
public static int fromBinary
(String b
) { }
}
aW1wb3J0IGphdmEuaW8uKjsKCnB1YmxpYyBjbGFzcyBCYXNlNjREZWNvZGUgewogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIC8vIOWkieaPm+ODhuODvOODluODqwogICAgICAgIGNoYXJbXSB0YWJsZSA9IHsJCiAgICAgICAgICAgICdBJywgJ0InLCAnQycsICdEJywgJ0UnLCAnRicsICdHJywgJ0gnLAogICAgICAgICAgICAnSScsICdKJywgJ0snLCAnTCcsICdNJywgJ04nLCAnTycsICdQJywKICAgICAgICAgICAgJ1EnLCAnUicsICdTJywgJ1QnLCAnVScsICdWJywgJ1cnLCAnWCcsIAogICAgICAgICAgICAnWScsICdaJywgJ2EnLCAnYicsICdjJywgJ2QnLCAnZScsICdmJywKICAgICAgICAgICAgJ2cnLCAnaCcsICdpJywgJ2onLCAnaycsICdsJywgJ20nLCAnbicsIAogICAgICAgICAgICAnbycsICdwJywgJ3EnLCAncicsICdzJywgJ3QnLCAndScsICd2JywgCiAgICAgICAgICAgICd3JywgJ3gnLCAneScsICd6JywgJzAnLCAnMScsICcyJywgJzMnLCAKICAgICAgICAgICAgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5JywgJysnLCAnLyd9OwoKICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG51bGw7ICAgIC8vIOWFpeWKm+ODh+ODvOOCvwogICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBudWxsOyAgLy8g5Ye65Yqb5YWICgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGluID0gbmV3IEZpbGVJbnB1dFN0cmVhbShhcmdzWzBdKTsKICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oYXJnc1sxXSk7CiAgICAgICAgICAgIGNoYXJbXSBjczsKICAgICAgICAgICAgd2hpbGUoKGNzPXJlYWQ0KGluKSkhPW51bGwpIHsKICAgICAgICAgICAgICAgIHdyaXRlMyhvdXQsIGNvbnZlcnQ2dG84KGRlY29kZShjcywgdGFibGUpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewogICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOyAgLy8g5L6L5aSW44Gu5oOF5aCx44KS6KGo56S644GZ44KLCiAgICAgICAgfSBmaW5hbGx5IHsgICAgLy8gaW4sIG91dCDjgpLplonjgZjjgosKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGluLmNsb3NlKCk7CiAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGludFtdIGRlY29kZShjaGFyW10gY3MsIGNoYXJbXSB0YWJsZSkgewogICAgICAgIGludFtdIHJldCA9IG5ldyBpbnRbY3MubGVuZ3RoXTsKICAgICAgICBmb3IoaW50IGk9MDsgaTxjcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBmb3IoaW50IGo9MDsgajx0YWJsZS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgaWYoY3NbaV0gPT0gdGFibGVbal0pIHsKICAgICAgICAgICAgICAgICAgICByZXRbaV0gPSBqOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBpbnRbXSBjb252ZXJ0NnRvOChpbnRbXSBidWYpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIGZiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBmb3IoaW50IGk9MDsgaTxidWYubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgZmIuYXBwZW5kKHRvQmluYXJ5KGJ1ZltpXSwgNikpOwogICAgICAgIH0KICAgICAgICBpbnRbXSByZXQgPSBuZXcgaW50W2ZiLmxlbmd0aCgpLzYtMV07CiAgICAgICAgZm9yKGludCBpPTA7IGk8cmV0Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIFN0cmluZyBmID0gZmIuc3Vic3RyaW5nKGkqOCwgaSo4KzgpOwogICAgICAgICAgICByZXRbaV0gPSBmcm9tQmluYXJ5KGYpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgfQoKICAgIC8qKgogICAgICog44OQ44Kk44OI5YiXIGJ0IOOBruaVsOOCkumghuOBq+WHuuWKm+OBmeOCiy4KICAgICAqIEBwYXJhbSBidCDmlbDjga7phY3liJfjgILplbfjgZXjga8gM+S7peS4iy4g5ZCE5pWw44GvOOODk+ODg+ODiOOBruaVtOaVsAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGUzKE91dHB1dFN0cmVhbSBvdXQsIGludFtdIGJ0KSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGZvciAoaW50IGk9MDsgaTwzOyBpKyspIHsKICAgICAgICAgICAgaWYgKGk8YnQubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBvdXQud3JpdGUoYnRbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogaW4g44GL44KJ5paH5a2X44KS5pyA5aSnNOOBpOiqreOBv+WHuuOBmS4KICAgICAqIEBwYXJhbSBpbiDlhaXlipvjgrnjg4jjg6rjg7zjg6AKICAgICAqIEByZXR1cm4g5paH5a2X44Gu6YWN5YiX44CC6YWN5YiX6ZW344Gv5pyA5aSnNC4g5YWl5Yqb57WC5LqG44GX44Gf44Go44GN44Gr44GvIG51bGwg44KS6L+U44GZLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNoYXJbXSByZWFkNChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBjaGFyW10gYnM7CiAgICAgICAgaW50IG4wPWluLnJlYWQoKTsKICAgICAgICBpbnQgbjE9aW4ucmVhZCgpOwogICAgICAgIGludCBuMj1pbi5yZWFkKCk7CiAgICAgICAgaW50IG4zPWluLnJlYWQoKTsKCiAgICAgICAgaWYgKG4wIDwgMCkgeyAgLy8g6Kqt44G/6L6844G/57WC5LqGCiAgICAgICAgICAgIGJzID0gbnVsbDsKICAgICAgICB9IGVsc2UgaWYgKG4yIDwgMCB8fCAoY2hhcikgbjI9PSc9JykgewogICAgICAgICAgICBicyA9IG5ldyBjaGFyWzJdOwogICAgICAgICAgICBic1swXSA9IChjaGFyKSBuMDsKICAgICAgICAgICAgYnNbMV0gPSAoY2hhcikgbjE7CiAgICAgICAgfSBlbHNlIGlmIChuMyA8IDAgfHwgKGNoYXIpIG4zPT0nPScpIHsKICAgICAgICAgICAgYnMgPSBuZXcgY2hhclszXTsKICAgICAgICAgICAgYnNbMF0gPSAoY2hhcikgbjA7CiAgICAgICAgICAgIGJzWzFdID0gKGNoYXIpIG4xOwogICAgICAgICAgICBic1syXSA9IChjaGFyKSBuMjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBicyA9IG5ldyBjaGFyWzRdOwogICAgICAgICAgICBic1swXSA9IChjaGFyKSBuMDsKICAgICAgICAgICAgYnNbMV0gPSAoY2hhcikgbjE7CiAgICAgICAgICAgIGJzWzJdID0gKGNoYXIpIG4yOwogICAgICAgICAgICBic1szXSA9IChjaGFyKSBuMzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJzOwogICAgfQoKICAgIC8qKgogICAgICog5pWw44KS6Kqt44G/5Y+W44Gj44Gm44CBbuODk+ODg+ODiOOBrjLpgLLmlbDjgpLooajjgZnmloflrZfliJfjgavlpInmj5vjgZnjgosKICAgICAqIEBwYXJhbSBidCAx44OQ44Kk44OI44Gu5pWwCiAgICAgKiBAcGFyYW0gbiAy6YCy5pWw44Gu44OT44OD44OI5pWwCiAgICAgKiBAcmV0dXJuIDLpgLLmlbDjgpLooajjgZnmloflrZfliJcKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9CaW5hcnkoaW50IGJ0LCBpbnQgbikgewogICAgICAgIFN0cmluZyBzID0gSW50ZWdlci50b0JpbmFyeVN0cmluZyhidCk7CiAgICAgICAgZm9yIChpbnQgaT1zLmxlbmd0aCgpOyBpPG47IGkrKykgewogICAgICAgICAgICBzID0gIjAiICsgczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICB9CgogICAgLyoqCiAgICAgKiAy6YCy5pWw44KS6KGo44GZ5paH5a2X5YiX44KS5pWw44Gr5aSJ5o+b44GZ44KLCiAgICAgKiBAcGFyYW0gYiAy6YCy5pWw44KS6KGo44GZ5paH5a2X5YiXCiAgICAgKiBAcmV0dXJuIGIg44GM6KGo44GZ5pWwCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGZyb21CaW5hcnkoU3RyaW5nIGIpIHsKICAgICAgICByZXR1cm4gSW50ZWdlci5wYXJzZUludChiLCAyKTsKICAgIH0KfQ==