Base64 인코딩 완벽 가이드: 원리부터 활용까지
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 비교
| 특성 | Base64 | Base64URL |
|---|---|---|
+ 문자 | + | - (하이픈) |
/ 문자 | / | _ (밑줄) |
패딩 = | 필수 | 선택적(생략 가능) |
| 주요 용도 | 이메일, 일반 데이터 | 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 변환이 필요할 때, 별도의 라이브러리를 설치하거나 코드를 작성할 필요 없이 브라우저에서 바로 사용하세요.