Base64 인코딩이 필요한 이유

파일, 이미지, PDF와 같은 데이터는 대부분 바이너리(Binary) 형태로 저장됩니다. 하지만 인터넷이나 JSON, XML과 같은 텍스트 기반 환경에서는 바이너리 데이터를 그대로 전달하기 어려운 경우가 있습니다.

이때 사용하는 대표적인 방법이 Base64 인코딩(Base64 Encoding)입니다.


왜 Base64를 사용할까?

예를 들어 Windows의 파일 하나를 다른 서버로 전송해야 한다고 가정해 보겠습니다.

C:\Windows\System32\keyboard.drv

이 파일은 단순한 문자열이 아니라 수많은 바이트(byte)로 이루어진 바이너리 데이터입니다.

만약 이 데이터를 문자열(String)로 억지로 변환해서 전송하면 어떻게 될까요?

  • 일부 바이트가 문자로 해석되지 못할 수 있습니다.

  • 문자 인코딩(UTF-8, EUC-KR 등)에 의해 데이터가 변경될 수 있습니다.

  • 결과적으로 원본 파일을 완벽하게 복원할 수 없게 됩니다.

즉, 바이너리 데이터를 일반 문자열처럼 처리하면 원본이 손상될 가능성이 있습니다.


Base64의 동작 원리

Base64는 바이너리 데이터를 손실 없이 안전한 문자열로 변환하는 인코딩 방식입니다.

전송 과정은 다음과 같습니다.

원본 파일(Byte[])
        │
        ▼
Base64 인코딩
        │
        ▼
문자열(String)
        │
        ▼
네트워크 전송
        │
        ▼
Base64 디코딩
        │
        ▼
원본 Byte[] 복원

이 과정을 거치면 파일의 내용이 변경되지 않으므로 원본을 그대로 복원할 수 있습니다.


바이너리 데이터 읽기

먼저 파일을 바이트 배열(byte[])로 읽어 보겠습니다.

public static void main(String[] args) throws IOException {

    File file = new File("C:/Windows/System32/keyboard.drv");
    FileInputStream fin = new FileInputStream(file);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int read;

    while ((read = fin.read(buffer)) != -1) {
        bos.write(buffer, 0, read);
    }

    fin.close();
    byte[] data = bos.toByteArray();
    System.out.println(data.length);
}

예를 들어 원본 파일의 크기가 2,000Byte라면 출력 결과 역시 2,000Byte가 됩니다.


왜 String으로 바꾸면 문제가 생길까?

바이트 배열은 문자 데이터가 아닙니다.

그런데 아래와 같이 문자열로 변환하면,

String text = new String(data);

Java는 현재 문자 인코딩(UTF-8 등)을 이용하여 바이트를 문자로 해석하려고 합니다.

하지만 바이너리 파일은 원래 문자 데이터가 아니므로 일부 바이트가 다른 문자로 변환되거나, 복원할 수 없는 형태로 변경될 수 있습니다.

즉, 문제의 원인은 byte가 signed이고 char가 unsigned라서가 아니라, 문자 인코딩 규칙을 적용하기 때문입니다.


Base64를 사용하면?

Base64는 바이너리 데이터를 문자로 안전하게 표현하도록 설계된 인코딩 방식입니다.

Java에서는 매우 간단하게 사용할 수 있습니다.

Base64 인코딩

String base64 = Base64.getEncoder().encodeToString(data);

입력은 byte[], 결과는 String입니다.

Base64 디코딩

byte[] restored = Base64.getDecoder().decode(base64);

입력은 String, 결과는 byte[]입니다.


주의할 점

Base64는 압축 기술이 아닙니다.

오히려 데이터를 문자열로 표현하기 위해 약 33% 정도 크기가 증가합니다.

예를 들어

원본 파일 : 2,000 Byte
        │
        ▼
Base64 인코딩
        │
        ▼
약 2,668 Byte

즉, Base64의 목적은 용량을 줄이는 것이 아니라, 바이너리 데이터를 손실 없이 문자열로 안전하게 전달하는 것입니다.


정리

  • 파일, 이미지, PDF 등은 바이너리(byte[]) 데이터이다.

  • 바이너리 데이터를 일반 String으로 변환하면 문자 인코딩 때문에 데이터가 변경될 수 있다.

  • Base64는 바이너리 데이터를 안전한 문자열로 변환하는 인코딩 방식이다.

  • 전송 후 Base64를 디코딩하면 원본 byte[]를 그대로 복원할 수 있다.

  • Base64는 압축이 아닌 인코딩이므로 데이터 크기가 약 33% 증가한다.