바이너리 인코딩은 컴퓨터가 데이터를 저장하는 가장 기본적인 형식입니다. 입력하는 모든 문자 — 알파벳, 숫자, 이모지 — 는 0과 1의 연속으로 저장됩니다. 이 글에서는 텍스트에서 바이너리로의 변환 원리, UTF-8 다중 바이트 인코딩, 그리고 코드 구현 방법을 설명합니다.
텍스트가 바이너리로 변환되는 과정
각 문자는 문자 인코딩 표준에 의해 숫자로 매핑되고, 그 숫자가 2진수(바이너리)로 표현됩니다. 현대 시스템은 UTF-8을 사용합니다. UTF-8은 ASCII와 하위 호환되며 전체 Unicode 문자 세트를 지원합니다.
ASCII 문자 (문자당 1바이트)
표준 ASCII 문자(코드 포인트 0–127)는 각각 정확히 1바이트(8비트)에 대응됩니다:
H = 72 = 01001000
e = 101 = 01100101
l = 108 = 01101100
l = 108 = 01101100
o = 111 = 01101111
“Hello”의 공백 구분 바이너리:
01001000 01100101 01101100 01101100 01101111
바이너리 값 읽는 방법
1바이트를 직접 디코딩하는 방법:
01001000
각 비트는 오른쪽에서 왼쪽으로 2의 거듭제곱을 나타냅니다:
위치: 7 6 5 4 3 2 1 0
비트: 0 1 0 0 1 0 0 0
값: 0 +64+ 0 + 0 + 8 + 0 + 0 + 0 = 72 = 'H'
UTF-8 다중 바이트 문자
UTF-8은 가변 길이 인코딩입니다. ASCII 범위 밖의 문자는 2, 3, 또는 4바이트를 사용합니다:
| 코드 포인트 범위 | 바이트 수 |
|---|---|
| U+0000 – U+007F | 1바이트 (ASCII) |
| U+0080 – U+07FF | 2바이트 |
| U+0800 – U+FFFF | 3바이트 (대부분의 한중일 문자) |
| U+10000 – U+10FFFF | 4바이트 (이모지, 희귀 문자) |
예시:
© (U+00A9) = 2바이트: 11000010 10101001
한 (U+D55C) = 3바이트: 11101101 10010101 10011100
😀 (U+1F600) = 4바이트: 11110000 10011111 10011000 10000000
같은 “문자 하나”라도 Unicode 표에서의 위치에 따라 생성되는 8비트 그룹 수가 다른 이유가 바로 이것입니다.
온라인 텍스트 → 바이너리 변환 도구
브라우저에서 즉시 변환하는 가장 빠른 방법:
- 텍스트 붙여넣기 → 바이너리 출력이 실시간 업데이트
- 공백 구분 (01001000 01100101…)과 연속 (0100100001100101…) 형식 선택 가능
- 바이너리 붙여넣기 → Binary → Text 클릭으로 텍스트 복원
- 모든 처리는 브라우저 내에서 실행 — 데이터는 서버로 전송되지 않음
코드 구현
JavaScript (브라우저)
브라우저 내장 TextEncoder API를 사용합니다:
function textToBinary(text) {
const encoder = new TextEncoder(); // 기본값은 UTF-8
const bytes = encoder.encode(text);
return Array.from(bytes)
.map(byte => byte.toString(2).padStart(8, '0'))
.join(' ');
}
console.log(textToBinary('안녕'));
// 11101010 10110000 10001010 11101100 10111001 10111001
console.log(textToBinary('Hi'));
// 01001000 01101001
바이너리를 텍스트로 복원:
function binaryToText(binary) {
const bytes = binary
.trim()
.replace(/\s+/g, ' ')
.split(' ')
.map(b => parseInt(b, 2));
const decoder = new TextDecoder('utf-8');
return decoder.decode(new Uint8Array(bytes));
}
console.log(binaryToText('11101010 10110000 10001010 11101100 10111001 10111001'));
// 안녕
Python
def text_to_binary(text: str) -> str:
return ' '.join(format(b, '08b') for b in text.encode('utf-8'))
def binary_to_text(binary: str) -> str:
parts = binary.strip().split()
return bytes(int(b, 2) for b in parts).decode('utf-8')
print(text_to_binary('안녕하세요'))
# 11101010 10110000 ...
print(binary_to_text('01001000 01100101 01101100 01101100 01101111'))
# Hello
커맨드 라인
python3 -c "
import sys
text = sys.argv[1]
print(' '.join(format(b, '08b') for b in text.encode('utf-8')))
" "안녕하세요"
공백 구분 vs 연속 형식
| 형식 | 예시 | 용도 |
|---|---|---|
| 공백 구분 | 01001000 01100101 | 사람이 읽기 쉬움, 각 바이트가 명확 |
| 연속 | 0100100001100101 | 압축적, 일부 프로토콜에서 사용 |
연속 형식을 디코딩할 때 문자열 길이는 반드시 8의 배수여야 합니다. 그렇지 않으면 바이너리 문자열이 불완전하거나 잘못된 형식입니다.
주요 활용 사례
학습 및 교육 — 바이너리 인코딩은 컴퓨터 과학의 핵심 기초 개념입니다. 자신의 이름을 2진수로 변환해 보면 문자와 바이트의 대응 관계를 직관적으로 이해할 수 있습니다.
인코딩 문제 디버깅 — 문자 깨짐이 발생했을 때 원시 바이너리를 확인하면 코덱 불일치, 다중 바이트 시퀀스 잘림, BOM 혼입 등의 원인을 찾을 수 있습니다.
CTF 및 보안 문제 — 텍스트와 바이너리 변환은 CTF(Capture The Flag) 대회에서 단골로 출제됩니다. 숨겨진 메시지가 바이너리로 인코딩된 경우가 많습니다.
프로토콜 및 파일 포맷 개발 — 바이너리 프로토콜이나 파일 포맷을 다룰 때 문자에서 바이트로의 매핑을 이해하는 것은 필수적입니다.
바이너리와 다른 인코딩 비교
| 인코딩 | ”Hi” 출력 | 크기 | 가독성 |
|---|---|---|---|
| 바이너리 | 01001000 01101001 | 가장 큼 | 매우 낮음 |
| 16진수 | 48 69 | 압축적 | 중간 |
| Base64 | SGk= | 원본의 약 4/3배 | 높음 |
| ASCII 10진수 | 72 105 | 압축적 | 중간 |
텍스트 안전한 압축 인코딩이 필요하다면 Base64 도구를, 10진수·16진수·8진수를 함께 확인하려면 ASCII Converter를 사용하세요.
요약
- 텍스트 → 바이너리: 각 문자를 UTF-8로 바이트로 인코딩한 뒤, 각 바이트를 8비트 바이너리로 표현.
- ASCII 문자는 1바이트; 이모지와 한글 등 많은 유니코드 문자는 2–4바이트.
- 공백 구분 형식은 바이트를 공백으로 구분; 연속 형식은 구분자 없음.
- JavaScript는
TextEncoder/TextDecoder, Python은.encode('utf-8')사용.