Base 64에는 어떤 문자와 기호를 쓰느냐에 따라 여러 변종이 있지만, 잘 알려진 것은 모두 처음 62개는 알파벳 A-Z, a-z와 0-9를 사용하고 있으며 마지막 두 개를 어떤 기호를 쓰느냐의 차이만 있다.
인코딩된 문자열은 알파벳 대소문자와 숫자, 그리고 "+", "/" 기호 64개로 이루어지며, "="는 끝을 알리는 코드로 쓰인다.
우선 24비트 버퍼에 위쪽(MSB)부터 한 바이트씩 세 바이트를 집어넣는다.
그리고 남은 바이트가 3바이트 미만이라면, 버퍼의 남은 부분은 0으로 채워넣게 된다.
그리고, 버퍼의 위쪽부터 6비트씩 잘라 그 값을 읽어,
다음에 정렬된 64개 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"의 문자 중에서 읽은 값 번째 문자를 골라 출력한다.
만약 입력된 바이트가 하나라면 출력 중 두 개만이 사용되고 나머지 둘은 "="으로 패딩되며,
입력된 바이트가 둘이라면 출력 중 세 개 만이 사용되고 나머지 하나는 "="으로 패딩되게 된다.
이것은 원본으로 되돌릴 때 원본에는 없던 비트가 생기는 것을 방지하기 위함이다.
이 과정을 입력 데이터가 끝날 때까지 반복하면 인코딩이 된다.
Incoder
import java.util.Scanner;
import java.util.StringTokenizer;
public class Base64_Incoder_Scanner {
public static void main(String[] args) {
String[] base64=new String[64];
String base="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (int i=0;i<base64.length;i++) {
base64[i]=base.substring(i, i+1);
}
Scanner sc = new Scanner(System.in);
int T; // 케이스 반복 횟수
//T = sc.nextInt();
String inputs; // 입력받은 문자열
char c; // 입력받은 문자열을 한글자씩 분리할때 담는 char
// (int) c; c를 아스키 코드로 변환
String code; // c를 2진수로 변환한 값(c를 아스키 코드로 변환한 것을 2진수로 변환한 것!)
String total_code = ""; // c를 모아 만든 것으로 최종적으로 입력받은 문자열을 2진수로 변환한 값이 저장됨
int bitode; // total_code(2진수)를 6자리씩 끊어 10진수로 계산한 수, binary to decimal
char atoword; // 2진수를 6자리씩 끊어 만든 10진수(아스키코드)를 char 타입으로 변환
String outputs; // 출력해줄 문자열
// T = Integer.parseInt(br.readLine().trim());
for (int test_case = 0; test_case < 1; test_case++) {
inputs = sc.nextLine();
//System.out.println("inputs="+inputs);
for (int i = 0; i < inputs.length(); i++) {
int j = 0;
c = inputs.charAt(i); // 입력받은 문자열중 한 글자를 의미
code = Integer.toBinaryString((int) c);
for (int cc=0;cc<8-code.length();cc++) {
total_code +=0;
}
total_code +=code; // 2진수로 변환된 코드!
//total_code+=" ";
}
int t=0; outputs="";
for (int i=t;i<inputs.length()*8/6;i++) {
bitode=0;
bitode+=Integer.parseInt(total_code.substring(t, t+1))*32;
bitode+=Integer.parseInt(total_code.substring(t+1, t+2))*16;
bitode+=Integer.parseInt(total_code.substring(t+2, t+3))*8;
bitode+=Integer.parseInt(total_code.substring(t+3, t+4))*4;
bitode+=Integer.parseInt(total_code.substring(t+4, t+5))*2;
bitode+=Integer.parseInt(total_code.substring(t+5, t+6))*1;
outputs+=base64[bitode];
t+=6;
}
System.out.print("#" + (test_case + 1) + " ");
System.out.println(outputs);
}
}
}
Sweet dreams are made of this. Who am I to disagree? I traveled the world and the seven seas. Everybody's looking for something
인코딩⇓ ⇑디코딩
U3dlZXQgZHJlYW1zIGFyZSBtYWRlIG9mIHRoaXMuIFdobyBhbSBJIHRvIGRpc2FncmVlPyBJIHRyYXZlbGVkIHRoZSB3b3JsZCBhbmQgdGhlIHNldmVuIHNlYXMuIEV2ZXJ5Ym9keSdzIGxvb2tpbmcgZm9yIHNvbWV0aGluZ
Encoder
import java.util.Scanner;
public class Base64_Encoder_Scanner {
public static void main(String[] args) {
char[] base64=new char[64];
String base="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (int i=0;i<base64.length;i++) {
base64[i]=base.charAt(i);
}
Scanner sc = new Scanner(System.in);
int T; // 케이스 반복 횟수
//T = sc.nextInt();
String inputs; // 입력받은 문자열
char c; // 입력받은 문자열을 한글자씩 분리할때 담는 char
int cnum=-1; // base64에 담겨있는 c의 index 번호
String code; //
String total_code;
int bitode; //
char atoword; //
String outputs; // 출력해줄 문자열
T = sc.nextInt();
for (int test_case = 0; test_case < T; test_case++) {
inputs = sc.next(); // 문자열 입력받음
//System.out.println("inputs="+inputs);
total_code="";
for (int i = 0; i < inputs.length(); i++) {
int j = 0;
c = inputs.charAt(i); // 입력받은 문자열중 한 글자를 의미
for (int cc=0;cc<base64.length;cc++) {
if(c==base64[cc]) {
cnum=cc;
}
}
code = Integer.toBinaryString(cnum);
for (int cc=0;cc<6-code.length();cc++) {
total_code +=0;
}
total_code +=code; // 2진수로 변환된 코드!
//total_code+=" ";
}
//System.out.println("total_code="+total_code);
//System.out.println("total_code길이="+total_code.length());
int t=0; outputs="";
for (int i=t;i<total_code.length()/8;i++) {
bitode=0;
bitode+=Integer.parseInt(total_code.substring(t, t+1))*128;
bitode+=Integer.parseInt(total_code.substring(t+1, t+2))*64;
bitode+=Integer.parseInt(total_code.substring(t+2, t+3))*32;
bitode+=Integer.parseInt(total_code.substring(t+3, t+4))*16;
bitode+=Integer.parseInt(total_code.substring(t+4, t+5))*8;
bitode+=Integer.parseInt(total_code.substring(t+5, t+6))*4;
bitode+=Integer.parseInt(total_code.substring(t+6, t+7))*2;
bitode+=Integer.parseInt(total_code.substring(t+7, t+8))*1;
//System.out.println(bitode+" ");
atoword=(char)bitode;
outputs+=Character.toString(atoword);
t+=8;
}
System.out.print("#" + (test_case + 1) + " ");
System.out.println(outputs);
//System.out.println(total_code);
}
}
}
Java Util
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
public class Base64_java_util {
public static void base64() {
String text="Sweet dreams are made of this.";
byte[] textBytes=text.getBytes();
// Base64 인코딩
Encoder encoder=Base64.getEncoder();
byte[] encodedBytes=encoder.encode(textBytes);
// Base64 디코딩
Decoder decoder=Base64.getDecoder();
byte[] decodedBytes=decoder.decode(encodedBytes);
System.out.println("원문\t : "+text);
System.out.println("인코딩 후\t : "+new String(encodedBytes));
System.out.println("디코딩 후\t : "+new String(decodedBytes));
}
public static void main(String[] args) {
base64();
}
}
+ 아파치에서 제공하는 라이브러리도 있음
'알고리즘 > 문제풀이 - JAVA' 카테고리의 다른 글
10진수 -> 2,8,16진수, 오름(내림)차순 정렬 (0) | 2020.09.07 |
---|---|
백준 13단계 브루트 포스 - 2798 블랙잭 (0) | 2020.04.03 |
백준 13단계 브루트 포스 - 7568 덩치 (0) | 2020.04.03 |
백준 11단계 재귀 - 10870 피보나치 5 (0) | 2020.04.02 |
백준 11단계 재귀 - 10872 팩토리얼 (0) | 2020.04.02 |