Toolypet
Back to Blog
Dev

Base64 인코딩 완벽 가이드: 원리부터 활용까지

Base64 인코딩의 작동 원리와 웹 개발에서의 실용적인 활용 방법을 알아봅니다.

Toolypet Team5 min read
Base64 인코딩 완벽 가이드: 원리부터 활용까지

Base64는 왜 만들어졌을까?

Base64의 탄생 배경을 이해하려면 1970년대 이메일 시스템으로 거슬러 올라가야 합니다. 당시 이메일 프로토콜인 SMTP는 오직 7비트 ASCII 문자만 전송할 수 있었습니다. 영문 알파벳과 숫자, 기본 기호만 지원되었고, 이미지나 문서 같은 바이너리 파일은 물론 한글 같은 멀티바이트 문자조차 전송이 불가능했습니다.

이 문제를 해결하기 위해 MIME(Multipurpose Internet Mail Extensions) 표준이 개발되었고, 그 핵심 기술 중 하나가 바로 Base64입니다. Base64는 어떤 바이너리 데이터든 안전한 ASCII 문자열로 변환해주므로, 텍스트만 처리할 수 있는 시스템에서도 파일을 전송할 수 있게 되었습니다.

오늘날에도 Base64는 여전히 널리 사용됩니다. 이메일 첨부파일, 웹 페이지의 인라인 이미지, API 인증, JWT 토큰 등 다양한 곳에서 만날 수 있습니다. 웹 개발자라면 반드시 이해해야 하는 기초 지식입니다.

Base64의 핵심 원리: 64개의 안전한 문자

Base64라는 이름은 64개의 문자를 사용한다는 데서 유래합니다. 이 64개 문자는 전 세계 거의 모든 시스템에서 안전하게 처리할 수 있도록 신중하게 선택되었습니다:

A-Z (26개) + a-z (26개) + 0-9 (10개) + + / (2개) = 64 문자

그리고 패딩을 위한 = 문자가 추가로 사용됩니다. 왜 64개일까요? 64는 2^6이므로, 6비트로 하나의 Base64 문자를 표현할 수 있습니다. 컴퓨터가 데이터를 처리하는 단위인 바이트(8비트)와 6비트 사이의 관계가 Base64 알고리즘의 핵심입니다.

인코딩 과정: 단계별로 이해하기

Base64 인코딩이 어떻게 작동하는지 "Man"이라는 문자열을 예로 살펴봅시다.

1단계: 각 문자를 8비트 이진수로 변환

M → 77  → 01001101
a → 97  → 01100001
n → 110 → 01101110

2단계: 24비트를 6비트씩 4개 그룹으로 분할

24비트(3바이트)를 6비트씩 나누면 4개의 그룹이 됩니다. 이것이 Base64가 데이터 크기를 약 33% 증가시키는 이유입니다. 3바이트 입력이 4문자(4바이트) 출력으로 변환되기 때문입니다.

010011 | 010110 | 000101 | 101110

3단계: 각 6비트를 Base64 문자로 변환

010011 → 19 → T
010110 → 22 → W
000101 → 5  → F
101110 → 46 → u

결과: "Man""TWFu"

패딩(=)의 역할

입력 데이터가 3바이트의 배수가 아니면 어떻게 될까요? 이때 패딩 문자 =가 사용됩니다.

예를 들어 "M"(1바이트)만 인코딩하면:

  • 8비트를 6비트 단위로 나누면 2비트가 남습니다
  • 4비트의 0을 추가하여 2개의 Base64 문자를 만듭니다
  • 나머지 2개 자리는 =로 채웁니다
"M" → "TQ=="
"Ma" → "TWE="
"Man" → "TWFu"

패딩은 디코딩 시 원본 데이터의 정확한 길이를 알 수 있게 해줍니다. 다만 URL에서 사용할 때는 패딩을 생략하기도 합니다.

웹 개발에서의 실전 활용

1. Data URI로 이미지 인라인하기

Data URI를 사용하면 이미지를 별도 파일 없이 HTML이나 CSS에 직접 포함할 수 있습니다.

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." />
.icon {
  background-image: url('data:image/svg+xml;base64,PHN2Zy...');
}

사용하면 좋은 경우:

  • 작은 아이콘(1-2KB 이하)
  • 반복적으로 사용되지 않는 이미지
  • HTTP 요청 수를 줄여야 하는 경우

피해야 할 경우:

  • 큰 이미지(33% 용량 증가가 부담됨)
  • 같은 이미지를 여러 페이지에서 사용(캐싱이 불가능)
  • 이미지가 자주 변경됨

2. HTTP Basic 인증

HTTP Basic 인증은 가장 단순한 인증 방식 중 하나입니다. 사용자 이름과 비밀번호를 콜론으로 연결한 후 Base64로 인코딩합니다.

const username = 'admin';
const password = 'secret123';
const credentials = btoa(`${username}:${password}`);

fetch('https://api.example.com/data', {
  headers: {
    'Authorization': `Basic ${credentials}`
  }
});

서버는 이 헤더를 디코딩하여 인증 정보를 추출합니다. 단, Base64는 암호화가 아니므로 반드시 HTTPS와 함께 사용해야 합니다. HTTP로 전송하면 누구나 비밀번호를 확인할 수 있습니다.

3. JWT(JSON Web Token) 구조

JWT는 세 부분으로 구성되며, 각 부분이 Base64URL로 인코딩됩니다:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.  // 헤더
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4ifQ.  // 페이로드
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c  // 서명

JWT에서 Base64URL을 사용하는 이유는 토큰이 URL의 쿼리 파라미터로 전달될 수 있기 때문입니다. 표준 Base64의 +/는 URL에서 특별한 의미를 가지므로, 안전한 문자로 대체합니다.

4. 파일 업로드

Ajax로 파일을 업로드할 때 FormData 대신 Base64 문자열로 전송하는 경우도 있습니다:

const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const reader = new FileReader();

reader.onload = function(e) {
  const base64 = e.target.result;
  // 서버로 전송
  fetch('/upload', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ file: base64 })
  });
};

reader.readAsDataURL(file);

이 방식은 JSON API와 함께 사용하기 편리하지만, 파일 크기가 33% 증가하므로 대용량 파일에는 적합하지 않습니다.

프로그래밍 언어별 사용법

JavaScript (브라우저)

// 인코딩
const encoded = btoa('Hello World');  // "SGVsbG8gV29ybGQ="

// 디코딩
const decoded = atob('SGVsbG8gV29ybGQ=');  // "Hello World"

주의: btoa()atob()는 라틴 문자만 지원합니다. 한글이나 이모지를 처리하려면:

// UTF-8 인코딩
function encodeUnicode(str) {
  return btoa(encodeURIComponent(str).replace(
    /%([0-9A-F]{2})/g,
    (_, p1) => String.fromCharCode('0x' + p1)
  ));
}

// UTF-8 디코딩
function decodeUnicode(str) {
  return decodeURIComponent(
    atob(str).split('').map(c =>
      '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    ).join('')
  );
}

Node.js

// 인코딩
const encoded = Buffer.from('Hello World').toString('base64');

// 디코딩
const decoded = Buffer.from(encoded, 'base64').toString('utf-8');

Python

import base64

# 인코딩
encoded = base64.b64encode(b'Hello World').decode('utf-8')

# 디코딩
decoded = base64.b64decode('SGVsbG8gV29ybGQ=').decode('utf-8')

# URL-safe Base64
url_safe = base64.urlsafe_b64encode(b'data').decode('utf-8')

Base64 vs Base64URL 비교

특성Base64Base64URL
+ 문자+- (하이픈)
/ 문자/_ (밑줄)
패딩 =필수선택적(생략 가능)
주요 용도이메일, 일반 데이터URL, 파일명, JWT

URL에서 +는 공백으로, /는 경로 구분자로 해석될 수 있습니다. Base64URL은 이러한 문제를 방지합니다.

흔히 하는 실수와 주의사항

1. Base64를 암호화로 착각 Base64는 인코딩이지 암호화가 아닙니다. 누구나 쉽게 디코딩할 수 있으므로 민감한 정보를 숨기는 용도로 사용하면 안 됩니다. 보안이 필요하다면 AES 같은 실제 암호화 알고리즘을 사용하세요.

2. 큰 파일에 Data URI 사용 Data URI는 캐싱이 불가능합니다. 100KB 이미지를 Base64로 변환하면 133KB가 되고, 페이지가 로드될 때마다 반복 다운로드됩니다. 외부 파일로 분리하면 브라우저 캐시의 혜택을 받을 수 있습니다.

3. 줄바꿈 문자 무시 일부 Base64 구현은 76자마다 줄바꿈을 삽입합니다(MIME 표준). 디코딩 전에 줄바꿈을 제거하지 않으면 오류가 발생할 수 있습니다.

4. 문자 인코딩 무시 btoa()로 한글을 직접 인코딩하면 에러가 발생합니다. UTF-8로 먼저 변환해야 합니다.

Toolypet Base64 도구 활용

Toolypet의 Base64 인코더/디코더는 개발자의 작업 흐름을 단순화합니다:

  • 텍스트 변환: 일반 텍스트를 Base64로, 또는 그 반대로 즉시 변환
  • 파일 변환: 이미지나 문서를 드래그 앤 드롭으로 Base64로 변환
  • Data URI 생성: 적절한 MIME 타입이 포함된 Data URI 자동 생성
  • UTF-8 자동 처리: 한글, 이모지 등 유니코드 문자 완벽 지원

개발 중 Base64 변환이 필요할 때, 별도의 라이브러리를 설치하거나 코드를 작성할 필요 없이 브라우저에서 바로 사용하세요.

Base64EncodingBinary DataWeb Development