Base64에 대한 심층적인 이해: 원리, 응용 및 프론트엔드 구현
Olivia Novak
Dev Intern · Leapcell

Base64에 대한 심층적인 이해: 원리, 응용 및 프론트엔드 구현
프론트엔드 개발에서 프로젝트 최적화는 성능 향상에 매우 중요한 부분입니다. 일반적인 최적화 전략 중 하나는 페이지의 HTTP 요청 수를 줄이기 위해 내장된 작은 이미지를 Base64 문자열로 적절하게 대체하는 것입니다. 이때, 이러한 이미지는 작은 이미지여야 하며, 일반적으로 특정 킬로바이트 수를 초과하지 않아야 한다고 강조합니다. 그렇다면 Base64는 정확히 무엇일까요? 그리고 왜 프론트엔드 최적화에서 중요한 역할을 할 수 있을까요? 함께 자세히 알아봅시다.
초기 이해
다음과 같은 문자열이 낯설지 않을 수 있습니다.
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......
이 고정된 형식을 통해 이미지를 나타낼 수 있으며, 브라우저는 이를 인식하고 해당 이미지를 완전히 표시할 수 있습니다. 위의 예는 SVG 형식의 이미지를 보여줍니다. 사실, 브라우저에서 지원하는 모든 형식으로 이미지를 로드할 수도 있습니다. 이 문자열은 Base64 인코딩을 기반으로 생성되었으며, base64,
뒤에 오는 긴 문자열이 Base64로 인코딩된 문자열입니다.
Base64의 탄생 배경
인터넷 개발 초기에는 이메일이 가장 효과적인 응용 프로그램 중 하나였습니다. 그러나 초기에는 이메일의 SMTP 전송 프로토콜이 7비트 ASCII 코드만 전송할 수 있었습니다. ASCII 코드는 영어를 기반으로 설계되었기 때문에 영어를 사용하지 않는 국가의 텍스트와 같은 리소스를 이 프로토콜을 통해 보낼 수 없었습니다. 이 문제를 해결하기 위해 나중에 MIME(Multipurpose Internet Mail Extensions)이 등장했습니다. MIME은 이메일의 주요 구조를 추가하고 ASCII가 아닌 코드에 대한 인코딩 및 전송 규칙을 정의했는데, 이것이 Base64의 기원입니다. 문자 인코딩에 대한 지식을 깊이 이해하고 싶다면 프론트엔드 개발에서 이해해야 할 문자 인코딩 지식을 참조할 수 있습니다.
기본 정의
Base64는 64개의 인쇄 가능한 문자를 기반으로 이진 데이터를 나타내는 인코딩 및 디코딩 방법입니다. 인코딩 및 디코딩 특성상 주요 기능은 보안이 아니라 다양한 게이트웨이 간에 콘텐츠가 오류 없이 전송되도록 하는 것입니다. 이 64개의 인쇄 가능한 문자에는 26개의 대문자 A - Z, 26개의 소문자 a - z, 10개의 숫자 0 - 9, 총 62개의 문자와 다른 두 문자 +
및 /
가 포함됩니다. Base64는 인덱스 기반 인코딩이며 각 문자는 인덱스에 해당합니다. 구체적인 관계도는 다음과 같습니다.
이것이 이름에 "64"가 들어간 이유이기도 합니다.
인코딩 방법
64는 2의 6승과 같으므로 Base64 문자는 실제로 6개의 이진 비트(bit)를 나타냅니다. 그러나 이진 데이터에서 1바이트는 8비트(bit)에 해당합니다. 따라서 3바이트(3 x 8 = 24비트)의 문자열 또는 이진 데이터는 4개의 Base64 문자(4 x 6 = 24비트)로 정확하게 변환될 수 있습니다. 왜 3바이트 단위로 그룹화될까요? 6과 8의 최소 공배수가 24이고 24비트가 정확히 3바이트이기 때문입니다. 구체적인 인코딩 방법은 다음과 같습니다.
- 매 3바이트를 그룹으로 묶습니다. 3바이트는 총 24개의 이진 비트를 가집니다.
- 이 24개의 이진 비트를 4개의 그룹으로 나누고 각 그룹은 6개의 이진 비트를 가집니다.
- 각 6개의 이진 비트 그룹 앞에 두 개의 00을 추가하여 32개의 이진 비트로 확장합니다. 즉, 4바이트입니다.
- 각 바이트는 64보다 작은 숫자에 해당하며, 이는 문자 번호입니다.
- 그런 다음 문자 인덱스 관계 테이블에 따라 각 문자 번호는 문자에 해당하며 Base64로 인코딩된 문자를 얻습니다.
예를 들어 위의 그림에서 문자열 two
가 변환되어 해당 인코딩을 얻습니다.
볼륨 증가
3개의 문자가 Base64 변환을 통해 인코딩되면 최종적으로 4개의 문자가 됩니다. 이는 각 6비트 위치에 2개의 0이 채워져 8비트 위치가 되어 1바이트에 해당하기 때문입니다. 여기서 정확히 1/3이 더 많습니다. 따라서 일반적으로 Base64로 인코딩된 데이터의 볼륨은 원본 데이터보다 1/3 더 큽니다. 이것이 앞에서 언급한 것처럼 Base64 인코딩을 사용하여 이미지를 최적화할 때 작은 아이콘이라고 강조해야 하는 이유입니다. 모든 이미지가 이러한 방식으로 처리되면 정적 파일이 크게 증가하여 적절하지 않습니다.
"=" 기호
세 개의 영어 문자는 정확히 4개의 Base64 문자로 변환될 수 있습니다. 문자 길이가 3의 배수가 아니면 어떻게 될까요? 어떤 규칙을 따라야 할까요? Base 인코딩을 실제로 사용할 때 우리는 종종 '=' 기호인 65번째 문자의 존재를 발견합니다. 이 등호 기호는 이러한 특수한 상황에 대한 처리 방법입니다. 3바이트 미만의 부분의 경우 실제로 0이 24개의 이진 비트가 될 때까지 끝에 추가됩니다. 그러나 바이트 수를 계산할 때 총 길이를 3으로 직접 나눠야 합니다. 나머지가 1이면 끝에 '='가 직접 추가됩니다. 나머지가 2이면 두 개의 '='가 추가됩니다. 따라서 트랜스코딩된 문자열에 추가해야 하는 접미사 등호는 1개 또는 2개입니다. 구체적인 상황은 다음 그림에서 확인할 수 있습니다.
그림에서 두 번째 경우, 단일 문자 d
는 인덱스 문자 테이블에서 인덱스 0을 구별하는 데 사용됩니다. 이때 획득한 인코딩에는 인덱스 0에 해당하는 A
문자가 있고 두 개의 '='가 직접 추가됩니다.
ASCII가 아닌 문자
Base64는 ASCII 문자만 인코딩할 수 있으므로 일본어 문자와 같은 ASCII가 아닌 문자의 경우 일본어 문자를 먼저 ASCII 문자로 변환한 다음 인코딩해야 합니다.
인코딩 및 디코딩 방법
btoa 및 atob
JavaScript는 Base64 인코딩 처리를 위한 두 가지 기본 메서드인 btoa()
와 atob()
를 제공합니다.
btoa()
: 문자열 또는 이진 값을 Base64로 인코딩된 문자열로 변환합니다.btoa
메서드는 ASCII 코드 문자만 직접 처리할 수 있습니다. ASCII가 아닌 코드 문자의 경우 오류를 보고합니다.atob()
: Base64로 인코딩된 문자열을 디코딩합니다.atob
메서드에 전달된 문자열 매개변수가 유효한 Base64 인코딩(예: ASCII가 아닌 문자)이 아니거나 길이가 4의 배수가 아니면 오류를 보고합니다.
btoa('you') // 'eW91' atob('eW91') // 'you' btoa('馬鹿') // Uncaught DOMException: The string to be encoded contains characters outside of the Latin1 range. atob('y') // Uncaught DOMException: The string to be decoded is not correctly encoded.
일본어 문자 처리
btoa
및 atob
는 ASCII 문자, 즉 단일 바이트 문자만 지원하므로 일반적으로 접하는 일본어 문자는 2 - 4 바이트 문자입니다. 따라서 일본어 문자를 먼저 UTF - 8 인코딩으로 변환하고 UTF - 8 인코딩을 문자로 간주하여 여러 단일 바이트 문자를 인코딩할 수 있습니다. 일본어의 경우 encodeURIComponent()
및 decodeURIComponent()
의 두 가지 메서드를 사용할 수 있습니다.
encodeURIComponent()
: ASCII가 아닌 문자를 UTF - 8로 인코딩합니다.decodeURIComponent()
: 디코딩에 사용됩니다.
다음은 일본어를 인코딩하고 디코딩하는 방법입니다.
window.btoa(encodeURIComponent('馬鹿')) // 'JUU5JUE2JUFDJUU5JUI5JUJG' decodeURIComponent(window.atob('JUU5JUE2JUFDJUU5JUI5JUJG')) // '馬鹿'
타사 라이브러리
예를 들어 js - base64
가 있습니다. 프론트엔드 개발에서 우리는 이러한 타사 라이브러리를 사용하여 Base64 관련 작업을 더 편리하게 처리할 수도 있습니다.
일반적인 프론트엔드 응용 프로그램
다음으로 프론트엔드 개발에서 Base64 인코딩의 일반적인 사용 시나리오를 살펴보겠습니다. 프론트엔드에서 Base64의 응용 프로그램은 대부분 이미지 처리와 관련이 있으며 일반적으로 DataURL 메서드를 기반으로 합니다. Data URL은 data:
접두사, MIME 유형(데이터 유형을 나타냄), base64
플래그(텍스트인 경우 선택 사항) 및 데이터 자체의 네 부분으로 구성됩니다. 구체적인 형식은 data:[<mime type>][;base64],<data>
입니다. 여기서 네 번째 부분인 <data>
, 즉 데이터 자체는 Base64 문자열입니다.
작은 이미지 트랜스코딩
즉, 처음에 언급한 이미지 최적화를 위한 요청 수를 줄이기 위해 Base64를 사용하는 시나리오입니다. img
태그 또는 css
에서 사용할 수 있습니다.
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......Ii8+PC9nPjwvc3ZnPg==">
.icon { background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......Ii8+PC9nPjwvc3ZnPg==); }
Vue 또는 React 프레임워크를 사용할 때 url - loader
를 통해 Base64로 변환할 아이콘의 크기를 설정하여 구성할 수도 있습니다.
.loader('url - loader') .tap(options => { options.limit = 10240 // 10kb return options })
파일 읽기
웹 환경에서 FileReader
API는 파일의 데이터를 읽기 위해 제공됩니다. readAsDataURL()
메서드를 사용하여 파일 데이터를 Base64로 인코딩된 문자열 데이터로 읽을 수 있습니다.
let reader = new FileReader() reader.onload = () => { let base64Img = reader.result }; reader.readAsDataURL(file)
이 방법은 일반적으로 이미지 업로드에 사용됩니다.
캔버스 이미지 생성
캔버스는 기본적으로 비트맵 이미지입니다. 캔버스를 이미지로 내보내는 toDataURL()
메서드를 제공하며, 이 이미지는 Base64로 인코딩된 형식으로 저장됩니다.
const dataUrl = canvasEl.toDataURL() // data:image/png;base64,PHN2ZyB4bWxucz0iaHR0c......
기타
이미지 표시 처리 외에도 Base64로 인코딩된 문자열은 특수 데이터 전송, 간단한 인코딩 및 암호화, 코드 난독화 및 일부 인증서에서도 볼 수 있습니다.
요약
마지막으로 Base64의 특징을 요약해 보겠습니다.
- 이진 데이터를 문자열(ASCII 코드)로 변환하여 데이터 전송을 용이하게 합니다.
- 브라우저는 Base64로 인코딩된 이미지를 직접 표시하여 요청을 줄일 수 있습니다.
- 인코딩된 데이터는 최소 1/3 더 커지고 인코딩 및 디코딩을 처리하기 위한 추가 방법이 필요합니다.
Base64를 깊이 이해함으로써 프론트엔드 개발에서 보다 합리적으로 사용하여 성능을 최적화하고 다양한 데이터 전송 및 표시 요구 사항을 더 잘 처리할 수 있습니다.
Leapcell: 웹 호스팅을 위한 차세대 서버리스 플랫폼
마지막으로 웹 서비스 배포를 위한 최고의 플랫폼인 **Leapcell**을 추천하고 싶습니다.
1. 다국어 지원
- JavaScript, Python, Go 또는 Rust로 개발하세요.
2. 무제한 프로젝트를 무료로 배포
- 사용량에 대해서만 지불하세요. 요청이나 요금이 없습니다.
3. 최고의 비용 효율성
- 유휴 요금 없이 사용한 만큼만 지불하세요.
- 예: $25로 평균 응답 시간 60ms에서 694만 건의 요청을 지원합니다.
4. 간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
5. 손쉬운 확장성 및 고성능
- 고도의 동시성을 쉽게 처리하기 위한 자동 확장.
- 운영 오버헤드가 없으므로 구축에만 집중하세요.
Leapcell Twitter: https://x.com/LeapcellHQ