본문 바로가기
C.W.K.
Stream
Lesson 05 of 06 · published

문자 인코딩 — UTF-8을 기본으로, 원본은 잃지 않게

~15 min · encoding, utf-8, unicode, bom

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

통제하는 텍스트 경계에는 UTF-8을 써

현대 파일·웹·소스의 보통 선택은 UTF-8이야. 다만 오래된 Windows 도구, CP949, 예전 Excel 출력처럼 다른 인코딩이 실제로 존재하므로 파일의 계약을 확인해.

BOM과 decode 오류를 읽어

utf-8-sig는 앞의 BOM이 있으면 없애고, utf-8은 문자로 남겨. UnicodeDecodeError는 어느 바이트 위치가 규칙에 맞지 않는지 알려주므로 무작정 무시하지 마.

추정은 증거가 아니야

chardet 같은 도구는 후보와 확률을 줄 뿐이야. 다시 얻기 어려운 자료는 원본 bytes를 먼저 보관하고 UTF-8 사본을 별도로 만들어 대표적인 한글·기호·줄바꿈을 확인해. errors='ignore'는 조용한 데이터 손실이야.

Code

현대 텍스트의 기본 UTF-8·python
# 한국어 텍스트는 UTF-8 에서 멀티바이트
text = "피파, 안녕"
b = text.encode("utf-8")
print(b)                     # b'\xed\x94\xbc\xed\x8c\x8c, \xec\x95\x88\xeb\x85\x95'
print(len(text))             # 6 글자
print(len(b))                # 17 바이트 — 한글 글자당 3 바이트

# Round-trip
back = b.decode("utf-8")
print(back == text)          # True
BOM이 있는 UTF-8 읽기·python
import io

# BOM 있는 파일 (Windows 메모장이 UTF-8 로 종종)
with_bom = b"\xef\xbb\xbfhello"

# utf-8 — BOM 첫 글자로 남음
print(with_bom.decode("utf-8"))         # '\ufeffhello'

# utf-8-sig — BOM 소비
print(with_bom.decode("utf-8-sig"))     # 'hello'

# BOM 있을 수 있는 파일 읽을 땐 utf-8-sig 선호
# BOM 있고 없고 둘 다 관용
UnicodeDecodeError의 위치 읽기·python
# CP949 = 한국 Windows 인코딩
text = "안녕"
cp949_bytes = text.encode("cp949")
print(cp949_bytes)            # b'\xbe\xc8\xb3\xe7'

# UTF-8 으로 디코드 시도 — 실패
try:
    cp949_bytes.decode("utf-8")
except UnicodeDecodeError as e:
    print("위치:", e.start)
    print("이유:", e.reason)
    # 에러가 디코딩 실패 위치 정확히 알려줘

# 맞는 인코딩으로 — 작동
print(cp949_bytes.decode("cp949"))     # '안녕'
대체 문자로 손실을 드러내기·python
messy = b"hello \xff world"           # 잘못된 UTF-8 바이트

# strict — raise
try:
    messy.decode("utf-8")
except UnicodeDecodeError as e:
    print("strict:", e)

# replace — 잘못된 바이트가 U+FFFD
print(messy.decode("utf-8", errors="replace"))   # 'hello \ufffd world'

# ignore — 잘못된 바이트 떨어뜨림
print(messy.decode("utf-8", errors="ignore"))    # 'hello  world'

# Backslash-escape — 보이는 표현
print(messy.decode("utf-8", errors="backslashreplace"))   # 'hello \\xff world'

# 표시엔 'replace', 드물게 'ignore', 코드엔 'strict' (디폴트)

External links

Exercise

한글, 영어, 이모지가 든 문자열을 UTF-8과 UTF-16으로 인코딩해 바이트 길이를 비교해. UTF-8의 한 글자 가운데 바이트를 0xFF로 바꿔 decode 오류를 확인하고 errors='replace'에서 U+FFFD가 남는 것도 봐.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.