레퍼런스6분 분량

URL 인코딩 vs Base64 인코딩: 무엇이 다를까?

URL 인코딩(퍼센트 인코딩)은 RFC 3986에 따라 URL 내 특수 문자를 %XX 형식으로 변환합니다. Base64 인코딩은 RFC 4648에 따라 64개의 ASCII 문자를 사용해 바이너리 데이터를 텍스트 문자열로 변환합니다. 두 방식은 목적이 서로 다르며 상호 호환되지 않습니다.

URL 인코딩이란?

퍼센트 인코딩이라고도 불리는 URL 인코딩은, URI에서 허용되지 않거나 특별한 의미를 갖는 문자를 표현하기 위한 방법으로 RFC 3986에 정의되어 있습니다. 인코딩할 각 문자는 (UTF-8을 사용해) 하나 이상의 바이트로 변환되며, 각 바이트는 퍼센트 기호(%)에 이어 두 자리의 대문자 16진수로 표현됩니다.

예를 들어 공백 문자는 %20이 되고, 앰퍼샌드는 %26이 되며, 유로 기호와 같은 비ASCII 문자는 %E2%82%AC(UTF-8 3바이트를 각각 퍼센트 인코딩한 것)가 됩니다.

// JavaScript에서의 URL 인코딩 예시
encodeURIComponent('hello world');   // "hello%20world"
encodeURIComponent('price=10&qty=2'); // "price%3D10%26qty%3D2"
encodeURIComponent('cafe');         // "caf%C3%A9"

URL 인코딩은 URL을 안전하고 유효하게 만들기 위해 특별히 설계되었습니다. URI에서 허용되지 않거나 예약된 의미를 갖는 문자만 인코딩하며, 영숫자와 몇몇 안전한 기호는 그대로 둡니다.

Base64 인코딩이란?

RFC 4648에 정의된 Base64 인코딩은 바이너리 데이터를 텍스트로 변환하는 인코딩 방식으로, 64개의 ASCII 문자 집합인 A-Z, a-z, 0-9, +, /를 사용하고 패딩에는 =를 사용합니다. 입력 3바이트마다 출력 4문자가 생성됩니다.

Base64는 이메일(MIME)이나 XML/JSON에 데이터를 삽입하는 경우처럼 텍스트만 안정적으로 지원하는 채널을 통해 바이너리 데이터를 전송하기 위해 설계되었습니다. URL에만 국한된 방식이 아니며, 특수 문자뿐 아니라 모든 입력 바이트를 인코딩합니다.

// JavaScript에서의 Base64 인코딩 예시
btoa('hello world');         // "aGVsbG8gd29ybGQ="
btoa('price=10&qty=2');      // "cHJpY2U9MTAmcXR5PTI="

// 유니코드 문자열은 먼저 UTF-8로 인코딩해야 합니다
function toBase64(str) {
  return btoa(unescape(encodeURIComponent(str)));
}
toBase64('cafe');           // "Y2Fmw6k="

Base64에는 +-로, /_로 바꾸고 흔히 = 패딩을 생략하는 URL 안전 변형(Base64url)도 있습니다. 이 변형은 JWT, URL 내의 data URI, 그리고 표준 Base64 문자가 URL 구문과 충돌할 수 있는 여러 상황에서 사용됩니다.

주요 차이점

항목 URL 인코딩 Base64 인코딩
표준 RFC 3986 RFC 4648
목적 URL을 안전하게 만들기 바이너리를 텍스트로 표현하기
인코딩 대상 특수/예약 문자만 모든 입력 바이트
출력 형식 %XX 16진수 시퀀스 A-Z, a-z, 0-9, +, /, =
크기 증가 가변적(인코딩된 문자만 늘어남) 항상 약 33% 증가
되돌리기 가능
사람이 읽기 쉬움 부분적으로(비예약 문자는 유지) 아니오
기본적으로 URL 안전 예(설계상) 아니오(+, /, = 포함)

언제 어떤 것을 써야 할까

URL 인코딩은 쿼리 매개변수 값, 경로 세그먼트, 프래그먼트 식별자처럼 URL에 특수 문자를 포함해야 할 때 사용합니다. 데이터를 URL 구조 안에 삽입해야 하는 모든 상황에서 URL 인코딩이 올바른 선택입니다.

Base64 인코딩은 바이너리 데이터(이미지, 파일, 암호화된 페이로드)를 텍스트로 표현하거나, 바이너리 콘텐츠를 JSON이나 XML에 삽입하거나, 텍스트 전용 채널로 데이터를 전송해야 할 때 사용합니다. Base64는 HTTP 기본 인증(Basic Authentication) 헤더와 JSON 웹 토큰(JWT)에도 사용됩니다.

// URL 인코딩: 검색어를 URL에 삽입하기
const searchUrl = 'https://example.com/search?q=' +
  encodeURIComponent('C++ & Java');
// "https://example.com/search?q=C%2B%2B%20%26%20Java"

// Base64: 이미지를 CSS나 HTML에 삽입하기
const imageData = 'data:image/png;base64,iVBORw0KGgoAAAANS...';

// Base64: HTTP 기본 인증 헤더
const credentials = btoa('username:password');
const header = 'Authorization: Basic ' + credentials;

둘을 함께 사용할 수 있을까?

가능하며, 경우에 따라서는 반드시 함께 써야 합니다. Base64로 인코딩된 데이터를 URL 매개변수로 전달해야 한다면, 표준 Base64 출력에는 URL에서 특별한 의미를 갖는 +, /, = 문자가 포함될 수 있습니다. 이때 두 가지 선택지가 있습니다.

옵션 1: Base64 문자열을 URL에 넣기 전에 URL 인코딩합니다. +%2B가 되고, /%2F가 되며, =%3D가 됩니다.

옵션 2: Base64url 변형(RFC 4648 5절)을 사용합니다. 이 방식은 +-로, /_로 바꾸고 패딩을 제거합니다. JWT와 여러 최신 API가 이 방식을 사용합니다.

// 옵션 1: 표준 Base64를 URL 인코딩하기
const base64 = btoa('binary data here'); // "YmluYXJ5IGRhdGEgaGVyZQ=="
const urlSafe = encodeURIComponent(base64);
// "YmluYXJ5IGRhdGEgaGVyZQ%3D%3D"

// 옵션 2: Base64url 인코딩
function toBase64url(str) {
  return btoa(str)
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}
toBase64url('binary data here');
// "YmluYXJ5IGRhdGEgaGVyZQ"

관련 글

무료 도구 사용해 보기