Base64, Base32, Base16은 바이너리 데이터를 텍스트 데이터로 인코딩하는 표준 방식으로, 바이너리 데이터를 안전하게 전송하거나 저장하기 위해 사용된다. 이는 주로 이메일, URL, 또는 파일 저장 시 인코딩에 사용된다.
Base64 는 64종류의 문자를 이용하기 때문에 인코딩 후에는 1문자당 6bit(64=2^6) 의 정보를 가진다.
- Base64: 64개의 문자 (A–Z, a–z, 0–9, +, /) → 6bit
- Base32: 32개의 문자 (A–Z, 2–7) → 5bit
- 숫자 2–7을 사용하는 이유는 혼동을 피하기 위해 (0과 O, 1과 I 구분)
- Base16: 16개의 문자 (0–9, A–F) → 4bit
특성 | Base64 | Base32 | Base16 |
사용 문자 수 | 64 (A–Z, a–z, 0–9, +, /) | 32 (A–Z, 2–7) | 16 (0–9, A–F) |
비트 처리 단위 | 6비트 | 5비트 | 4비트 |
출력 증가율 | 약 33% 증가 | 약 60% 증가 | 100% 증가 |
패딩 문자 | = | = | 없음 |
목적 | 압축된 텍스트 변환 | 사람이 구분하기 쉬운 텍스트 | 간단한 텍스트 변환 |
주요 사용 사례 | 이메일(MIME), jwt, 웹 전송, url data | QR 코드, 사람 읽기 가능 환경 | 디버깅, 해시값 출력 |
Base64 특징
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
- 64개의 문자와 패딩 문자 '=' 사용:
- Base64는 ASCII 문자 65개를 사용
- 대문자: A–Z (0–25)
- 소문자: a–z (26–51)
- 숫자: 0–9 (52–61)
- 특수 문자: + (62), / (63)
- 패딩 문자: = (부족한 데이터 채우기)
- Base64는 ASCII 문자 65개를 사용
- 6비트 단위로 처리:
- 데이터를 6비트 단위로 나누어 각 6비트를 Base64 문자로 변환.
- 입력 데이터는 24비트(3바이트) 단위로 처리됨.
- 3바이트(24비트) → 4문자(6비트 × 4)로 인코딩.
- 패딩 처리:
- 입력 데이터의 길이가 3의 배수가 아닐 경우:
- 부족한 비트를 0으로 채운 뒤 결과에 = 문자 추가.
- 예: 입력이 1바이트일 경우 ==, 2바이트일 경우 = 추가.
- 입력 데이터의 길이가 3의 배수가 아닐 경우:
- 결과 문자열은 항상 4의 배수 길이:
- 패딩(=)으로 결과 문자열의 길이를 4의 배수로 맞춤.
Base64 인코딩 과정
#include <iostream>
#include <string>
using namespace std;
// Base64 문자 테이블
const string base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
string encodeBase64(const string& input) {
string encoded;
int val = 0, valBits = 0; // 비트 값을 저장할 변수와 누적 비트 길이
const int paddingBits = 6; // Base64는 6비트 단위로 처리
for (unsigned char c : input) {
val = (val << 8) | c; // 기존 비트를 8칸 왼쪽으로 밀고 새로운 비트를 추가
valBits += 8; // 현재 비트 길이 누적
while (valBits >= paddingBits) { // 6비트 단위로 처리
encoded += base64Chars[(val >> (valBits - paddingBits)) & 0x3F]; // 상위 6비트를 추출
valBits -= paddingBits; // 처리된 비트 길이를 감소
}
}
if (valBits > 0) { // 남은 비트를 처리 (패딩 필요)
encoded += base64Chars[(val << (paddingBits - valBits)) & 0x3F]; // 남은 비트를 왼쪽으로 밀고 추가
}
// 패딩 문자 '=' 추가
while (encoded.size() % 4 != 0) {
encoded += '=';
}
return encoded;
}
int main() {
string input;
cout << "Enter the string to encode: ";
getline(cin, input);
string encoded = encodeBase64(input);
cout << "Encoded Base64: " << encoded << "\n";
return 0;
}
- 입력 데이터를 3바이트 단위로 읽음.
- 3바이트를 24비트로 결합.
- 이 24비트를 6비트씩 4개의 그룹으로 나눔.
- 각 6비트를 Base64 문자로 변환하여 결과 문자열에 추가.
- 부족한 데이터는 0으로 채우고, =로 패딩 처리.
Base64 디코딩 과정
#include <iostream>
#include <string>
#include <map>
#include <algorithm> // reverse 함수 사용
using namespace std;
// Base64 문자 → 값 매핑을 저장할 전역 변수
map<char, int> base64Map;
// 24비트 데이터를 입력받아 8비트 단위로 문자열로 변환하는 함수
string decode24BitTo8Bit(int data) {
string decoded;
for (int i = 16; i >= 0; i -= 8) { // 24비트를 8비트 단위로 분리
char byte = (data >> i) & 0xFF; // 상위 8비트를 추출
if (byte != 0) decoded += byte; // 유효한 값만 추가
}
return decoded;
}
// Base64 디코딩 함수
string decodeBase64(const string& input) {
string result;
int data = 0, charCount = 0;
for (char ch : input) {
if (ch == '=') continue; // Padding 문자 무시
data = (data << 6) | base64Map[ch]; // 6비트씩 이동 후 추가
charCount++;
if (charCount == 4) { // 4문자(24비트) 단위로 처리
result += decode24BitTo8Bit(data);
data = 0; // 다음 24비트를 위해 초기화
charCount = 0; // 문자 카운터 초기화
}
}
return result;
}
int main() {
// Base64 문자 → 값 매핑 초기화
for (char i = 'A'; i <= 'Z'; i++) base64Map[i] = i - 'A'; // A-Z: 0-25
for (char i = 'a'; i <= 'z'; i++) base64Map[i] = i - 'a' + 26; // a-z: 26-51
for (char i = '0'; i <= '9'; i++) base64Map[i] = i - '0' + 52; // 0-9: 52-61
base64Map['+'] = 62;
base64Map['/'] = 63;
// 입력받은 Base64 문자열 디코딩
string input;
cin >> input;
string decoded = decodeBase64(input);
cout << decoded << "\n";
return 0;
}
- 4문자 단위로 처리:
- Base64 문자열을 읽어 6비트 값으로 변환.
- 24비트 복원:
- 변환된 6비트 값들을 다시 결합하여 24비트(3바이트) 복원.
- 패딩 무시:
- = 문자는 디코딩 과정에서 무시되며, 복원된 바이트 수에 따라 결과를 생성.
Base64 URL 및 파일 이름 Safe Alphabet
- Base64를 URL 및 파일 이름에서 안전하게 사용할 수 있도록 변형한 버전.
- 일반 Base64와 동일하나, 일부 문자를 대체:
- + → -
- / → _
- 패딩 문자 =는 URL에서 퍼센트 인코딩(%3D)이 필요하므로 생략 가능.
References
'알고리즘' 카테고리의 다른 글
[Crypto] NEAT, NES (0) | 2024.12.03 |
---|---|
Google authenticator를 사용한 2FA 인증 #1 이론 (1) | 2024.11.21 |
Kalman Filter and Sensor Fusion #1 How it work (0) | 2024.08.15 |
deflate: LZ77 + Huffman coding (0) | 2024.08.15 |