[JAVA] Base64란 무엇인가

Welcome to Seoyun Dev Log·2023년 4월 17일
1

JAVA

목록 보기
7/12

인코딩(Encoding)과 디코딩

인코딩

  • 파일에 저장된 정보의 형태나 형식을(예를 들어 실행 파일이나, ZIP 파일 등) 데이터 표준화, 보안, 처리 속도 향상, 저장 공간 절약 등을 위해서 다른 형태로 변환하는 처리 혹은 그 처리 방식
  • 문자나 기호들의 집합을 컴퓨터에 저장하거나 통신에 사용할 목적으로 부호화하는 방법

디코딩

  • 인코딩의 반대 작업으로 복호화라고 하는데 부호화된 정보를 부호화되기 전으로 되돌리는 처리 방식

Base64를 쓰는 이유?

Base64는 HTML 또는 Email과 같이 문자를 위한 Media에 Binary Data를 포함해야 될 필요가 있을 때 포함된 Binary data가 시스템 독립적으로 동일하게 전송 또는 저장되는것을 보장하기 위해서 사용

Base64를 인코딩할 경우 6bit당 2bit의 overhead가 발생하기 때문에 전송해야 될 데이터의 양이 약 33% 늘어나고 인코딩, 디코팅에 추가 CPU 연산까지 필요한데
그럼에도 불구하고 사용하는 이유는

  • 문자를 전송하기 위해 설계된 Media(Email, HTML)를 이용하여 Binary Data(이미지, 오디오)를 전송할 때 ASCII로 인코딩하여 전송하게 되면 여러가지 문제가 발생할 수 있다
    • ASCII는 7bits Encoding 인데 나머지 1bit를 처리하는 방식이 시스템 별로 상이하다
    • 일부 제어문자 (ex: Line ending)의 경우 시스템 별로 다른 코드값을 갖음

위와 같은 이유로 ASCII는 시스템간 데이터를 전달하기에 안전하지 않다.
따라서 ASCII중 제어문자와 일부 특수문자를 제외한 64개의 안전한 출력 문자(문자 코드에 영향을 받지 않는 공통 ASCII를 의미)만 사용하는 Base64를 사용하는 것


Base64

Base64는 Binary Data(8비트 이진 데이터)를 텍스트로 변경하는 인코딩 방식 중 하나로 바이너리 데이터를 문자 코드에 영향을 받지 않는 공통 64개의 ASCII 영역의 문자들로 이루어진 문자열로 변경합니다.

  • 64가 2의 제곱수(64 = 26)이며, 2의 제곱수들에 기반한 진법들 중에서 화면에 표시되는 ASCII 문자들을 써서 표현할 수 있는 가장 큰 진법
  • 보안을 위해 사용하는 것이 아니라, 바이너리 데이터(이진)를 텍스트로 다루고 싶을 때 사용
  • 신뢰할 수 없는 통신 채널을 통해 바이너리 데이터를 안전하게 전송할 수 있도록 사용
  • 통신 과정에서 바이너리 데이터의 손실을 막기 위해 사용

변환 과정

  1. 문자열을 ASCII로 치환
    (M -> 77)
  2. 치환한 ASCII 값을 바이너리 데이터로 치환
    (77 -> 01001101) 십진수로 변환
  3. 바이너리 데이터 값을 이은 후 6bit씩 자른 후 Base64 색인표에 나와 있는 데이터로 치환

Java Base64 Encode, Decode

자바를 이용해 Base64 인코딩 디코딩하는 방법
주의해야 할점은 String <-> byte[] 간의 변환에 대해 신경써주면 된다.
encoding 할때는 byte[] 를 param으로 넣어주고
decoding 할때는 decode 결과를 String으로 변환을 해주는 정도만 신경쓰면 아주 쉽게 이용할 수 있다.

  • 자바 8 기본 라이브러리(java.util.Base64)
    • java.util.Base64 유틸리티 클래스를 통해 표준 API에 Base64 기능을 추가
import static java.util.Base64.*;

public class Base64Test {
    public static void main(String[] args) {
        String test = "안녕하세요 저는 개발자입니다";
        byte[] testBytes = test.getBytes();

        Encoder encoder = getEncoder();
        Decoder decoder = getDecoder();

        byte[] encodeByte = encoder.encode(testBytes);
        byte[] decodeByte = decoder.decode(encodeByte);

        System.out.println(test);
        System.out.println(new String(encodeByte));
        System.out.println(new String(decodeByte));
    }
}

//출력
인코딩 전: 안녕하세요 저는 개발자입니다
인코딩: 7JWI64WV7ZWY7IS47JqUIOyggOuKlCDqsJzrsJzsnpDsnoXri4jri6Q=
디코딩: 안녕하세요 저는 개발자입니다

패딩

Base64 인코딩에서 출력 인코딩된 문자열의 길이는 3의 배수여야 한다. 인코더는 이 요구 사항을 충족하기 위해 필요에 따라 출력 끝에 하나 또는 두 개의 패딩 문자(=)를 추가한다.

  • 디코딩시 이러한 추가 패딩 문자는 삭제
  • 출력의 패딩을 건너 뛰어야하는 경우 (아마도 결과 문자열이 다시 디코딩되지 않기 때문에) 패딩없이 인코딩 하도록 선택할 수 있습니다)

Url 인코딩

URL을 인코딩하기 위해 기본 인코딩을 사용할 수 없습니다. 또한 URL 및 파일 이름 Safe Base64 알파벳을 사용한다. 또한 줄 구분을 추가하지 않는다.

  • 인코딩
String originalUrl = "https://www.google.co.nz/?gfe_rd=cr&ei=dzbFV&gws_rd=ssl#q=java";
String encodedUrl = Base64.getUrlEncoder().encodeToString(originalURL.getBytes());
  • 디코딩
byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedUrl);
String decodedUrl = new String(decodedBytes);
  • 인코딩의 안전성을 위해 encodeBase64URLSafeString을 권장

profile
하루 일지 보단 행동 고찰 과정에 대한 개발 블로그

0개의 댓글