CodeGym /행동 /C# SELF /인코딩이 뭔지, 그리고 왜 필요한지

인코딩이 뭔지, 그리고 왜 필요한지

C# SELF
레벨 37 , 레슨 0
사용 가능

1. 도입

국제 정상 회담에 온 외교관이라고 상상해봐요: 각자 다른 언어와 문자 체계를 쓰죠. 서로 이해하려면 공통 번역 규칙이 필요해요 — 문자들을 서로 대응시키는 규칙 집합이요. 컴퓨터에서는 그 역할을 인코딩이 합니다.

컴퓨터는 오직 한 가지 "언어"만 이해해요 — 0과 1의 연속. 01이 그 "알파벳"이죠. 모든 정보는 바이트 단위로 저장되고 전송됩니다. 하나의 바이트는 8비트예요(예: 01000001).

그렇다면 우리의 문자와 기호들을 바이트와 어떻게 연결할까요? 컴퓨터는 어떻게 문자 'А'가 단순한 0/1의 집합이 아니라 화면에 나오는 특정 심볼이라는 걸 알까요?

인코딩

인코딩은 각 문자(글자, 숫자, 기호, 한자, 이모지 등)를 바이트의 연속으로 변환하고, 다시 그 바이트들을 문자로 해석하는 방법을 정의하는 규칙(대응 테이블)입니다.

비유하자면 모스 부호와 같아요: 텍스트를 점과 대시로 바꿔 전송하면, 받는 쪽은 같은 규칙으로 원래 문자를 복원하죠. 컴퓨터에서 "바이트 ↔ 문자"에 대한 합의가 바로 인코딩입니다.

2. 왜 인코딩 때문에 골치 아픈가?

  • 사람 세계와 기계 세계의 번역: 인코딩 없이는 텍스트가 단순한 바이트 덩어리일 뿐이고, 인코딩이 있으면 의미 있는 문자들이 됩니다.
  • 호환성과 범용성: 서로 다른 프로그램과 OS가 같은 규칙으로 합의해야 해요. 파일이 UTF-8로 저장되어 있다면, 읽을 때도 UTF-8으로 읽어야 합니다.
  • 다양한 언어와 문자 지원: 키릴 문자, 아랍 문자, 한자, 수학 기호, 이모지 등 — 표현해야 할 문자가 많아질수록 인코딩은 더 복잡하고 유연해야 합니다.

3. ASCII – '원시적인' 인코딩

가장 오래되고 기본적인 인코딩 중 하나는 ASCII(American Standard Code for Information Interchange)예요. 이건 문자당 7비트를 사용해서 총 128개의 서로 다른 문자를 표현할 수 있어요: 라틴 문자(A-Z, a-z), 숫자(0-9), 구두점과 제어 코드(예: 줄 바꿈, 탭) 등이죠.

문자 십진수 코드 (ASCII) 이진 코드 (7비트)
A
65
1000001
B
66
1000010
a
97
1100001
b
98
1100010
0
48
0110000
1
49
0110001
!
33
0100001
공백
32
0100000

역사적으로 8번째 비트는 종종 패리티 비트로 사용됐고, 이후에는 그 비트를 지역별로 다른 확장 문자 집합에 쓰기 시작했어요 — 그래서 다양한 1바이트 인코딩들이 생겨서 혼란이 발생했죠.

예를 들어 "Hello"를 쓰면 디스크에는 대략 이렇게 저장됩니다(문자당 1바이트; 7비트 ASCII의 경우 상위 비트는 0):

H (01001000) e (01100101) l (01101100) l (01101100) o (01101111)

간단하죠. 그런데 러시아 문자나 한자는 어디에 있나요? ASCII에는 그런 문자가 없어요 — 기본 라틴 문자용의 "단일 언어 사전"일 뿐입니다.

4. '깨진 문자(크라코зя브ры)' — 인코딩 문제가 농담이 아닌 이유

가끔 파일을 열면 Привет 같은 걸 보게 되고 원래는 "Привет"였을 때가 있어요. 이걸 흔히 '크라코зябр(кракозябры)' 또는 Mojibake라고 부르는데, 잘못된 인코딩으로 바이트를 읽었을 때 생기는 현상이에요.

예를 들어 "Привет, мир!"을 Windows-1251로 저장했을 때, "Привет"에 해당하는 바이트들이 (단순화해서) 이렇게 나올 수 있어요:

  • П207
  • р240
  • и232
  • в226
  • е229
  • т242

그런데 동료가 그 파일을 ISO-8859-1(Latin-1)을 기대하는 편집기로 열었거나, 여러분이 StreamReader를 인코딩 없이 사용해서 자동으로 선택된 인코딩이 파일의 인코딩과 안 맞았다면, 결과는 바이트 207이 다른 테이블의 문자로 해석되는 식으로 텍스트가 깨지는 겁니다.

원래 문자 (Windows-1251) 바이트 표현 (예) ISO-8859-1로 읽었을 때의 문자
П
207
Ç
р
240
à
и
232
è
в
226
â
е
229
å
т
242
ò

결국 Çàèâåò 같은 게 나오고 원래의 "Привет" 대신 이상한 문자열이 보이게 돼요. 만약 기대하는 인코딩에 해당 문자가 전혀 없다면, 사각형 박스나 물음표가 대신 보이기도 합니다.

실무에서의 핵심 교훈: 텍스트를 읽고 쓸 때는 특히 데이터의 출처를 여러분이 통제하지 못하는 경우, 인코딩을 명시적으로 지정하는 게 중요해요. .NET에서는 StreamReader/StreamWriter에서 원하는 Encoding을 지정해서(예: UTF-8 또는 Encoding.GetEncoding("windows-1251")) 이런 크라코зя브르를 피하고 시스템 간에 올바른 데이터 교환을 보장할 수 있습니다.

다음 강의들에서는 파일과 스트림 작업 시 인코딩을 자신 있게 선택하고 지정하는 방법을 배워서, 여러분의 코드가 국제화되어 있고 안정적으로 동작하게 만들 거예요.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION