왜 base64를 사용하는가?
이진(Binary) 데이터를 64개의 ASCII 문자로 구성된 문자열로 변환하는 인코딩 방식
텍스트 기반 시스템에서도 이진 데이터를 안전하게 전송할 수 있다는 장점이 있다.
예시로, 이메일과 같은 텍스트 기반 프로토콜에서 이미지를 첨부할 때, 이미지를 base64로 변환해서 전송하면 데이터 손실 없이 안전하게 전달할 수 있다.
실무에서는 api 키 등을 base64로 인코딩해서 사용하는 경우등이 있는데,
이 경우, 암호화로써 역할은 하지 않지만, Http 헤더로 안전하게 전송을 보장한다.
인코딩 과정
우선, 8비트 이진 데이터로 바꿔준다.
| 구분 | |||||
|---|---|---|---|---|---|
| 문자 | H | e | l | l | o |
| 8-bit 이진 숫자 | 01001000 | 01100101 | 01101100 | 01101100 | 01101111 |
0100100001100101011011000110110001101111
이렇게 나온 데이터를, 6비트 단위로 쪼개서 나눠주고
010010 000110 010101 101100 011011 000110 1111
이때, 마지막 6비트를 채우기 2자리가 부족하므로, 0으로 채우고, = 문자로 패딩처리한다.
인코딩 문자열의 길이가 4의 배수가 되도록 보장하기 위해 사용하며
디코딩할때 문자열의 개수를 알려줄때에도 사용한다.
패딩의 개수는 다음과 같다.
원본 데이터가 3의 배수 바이트: 패딩 x
원본 데이터가 3n+2 바이트: 패딩 '=' 하나
원본 데이터가 3n+1 바이트: 패딩 '=' 두 개
Hello는 40bit이므로 패딩 한개에 해당하게 된다.
010010 000110 010101 101100 011011 000110 111100=
해서 최종적으로 64비트, BASE64로 인코딩을 하게된다면?
| 6-bit 그룹 | 010010 | 000110 | 010101 | 101100 | 011011 | 000110 | 111100= | |
| 10진수 변환 값 | 18 | 6 | 21 | 44 | 27 | 6 | 60= | |
| Base64 문자 | S | G | V | s | b | G | 8= |
최종값은 SGVsbG8= 라는 값이 나오게 된다!
예시로 한글 이라는 문자를 인코딩해 보자.
한글은 UTF-8을 사용해서, 3바이트를 사용하고 있다.
각각의 글자를 10진수로 나타내면
각 바이트를 이진수로 변환합니다.
111011 011001 010110 011100 111010 101011 100010 000000
따라서 한글은 7ZWc6riA 로 인코딩할수 있겠다.
https://vivoldi.com/tools/base64-encoding-decoding
사이트에서 검증해보길 바란다!
https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html
자바에서는 Base64 클래스를 지원해준다.
인코딩에는 encodeToString,
디코딩에는 decode
메서드를 사용한다.
import java.util.Base64;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
Base64.Encoder encoder = Base64.getEncoder(); // base64, 인코더
String encoded = encoder.encodeToString(input.getBytes()); // 변환
System.out.println(encoded);
}
}
import java.util.Base64;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
Base64.Decoder decoder = Base64.getDecoder(); // base64, 디코더 선언
String decoded = new String(decoder.decode(input)); //변환
System.out.println(decoded);
}
}
Base64 인코딩에서는 +와 /를 사용하게 되는데,
url에서는 이 문자들에서 중요한 의미를 가지므로, 대체해서 사용하게 된다.
이외의 모든 규칙은 동일하며, 패딩 문자는 브라우저에서 인식하지 않게 처리
자바에서는 동일한 클래스로 사용할수 있으며, 메서드명만 다르게
String sampleUrl = "https://www.google.com/search?q=Base64+encode";
String encodingUrl = Base64.getUrlEncoder().encodeToString(sampleUrl.getBytes());
// 결과: aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9zZWFyY2g_cT1CYXNlNjQrZW5jb2Rl
이러한 방식으로 사용할수 있겠다.
참고자료 - 토스 페이먼트 개발자센터 Base64
https://docs.tosspayments.com/resources/glossary/base64