Post

문자 인코딩 방식

문자 인코딩 방식

언어의 지역화란?

프로그래머가 반드시 알아야 하는 것이 언어의 지역화입니다. 한국어를 사용하는 게임을 미국에 출시하려면 NPC의 대사나 퀘스트, 케릭터 이름, 심지어 게임 무비의 대사까지도 영어가 되어야 합니다. 반대로 미국에서 출시한 게임을 한국에 출시하기 위해선 모든 영어를 한국어로 바꾸어야 하죠.

컴퓨터에서 영어(알파벳)를 표현하는 방법

컴퓨터는 숫자 밖에 알지 못합니다. 0~9까지 알기도 함들어서 0과 1밖에 알지 못합니다. 하지만 어떻게 우리 모니터 화면에는 0~9가, ‘ABC..’ ‘abc..’ 등등의 알파벳들이 떡하니 있는 걸까요? 다음과 같이 0,1로 된 숫자 세트를 문자와 연결시키면 되겠죠.

0000 = 0
0001 = 1
0010 = 2
0011 = 3

그 뿐만 아니라 다음과 같이 연결할 수도 있습니다.

0000 = a
0001 = b
0010 = c
0011 = d

그래서 0000을 보여주라고 하면 1번 방식의 컴퓨터에서는 0를 보여주고 2번 방식에서는 a를 보여줍니다. 여기서 문제가 발생하겠네요. 1번 방식의 컴퓨터에서 텍스트 파일에 “123”을 저장해 2번 방식의 컴퓨터에게 준다면, 텍스트 파일을 여는 순간 “123”이 아닌 “bcd”가 보이겠죠? 이건 아주 중요한 문제입니다. 전 “안녕?” 이라고 보냈는데 상대방은 “꺼져!”로 받을 수 있으니까요. 그래서 Standard라는 것이 생겨나 “모두 이런 방식으로 숫자와 문자를 연결해 주세요!” 라고 독려를 하는 것입니다. 이것에 관한 최초의 Standard가 ASCII였습니다.

최초의 인코딩 표준 : ASCII Code

아스키 코드는 큰 장점이 있습니다. 바로 그것이 128개의 문자만을 표현하고 있다는 것인데 그것은 1byte의 메모리의 절반만을 (0000 0000 ~ 0111 1111) 사용해서 다 표현할 수 있는 숫자입니다. 하지만 그것은 동시에 아스키의 단점이기도 하였습니다. 아스키가 표현할 수 있는 문자는 알파벳 소문자, 알파벳 대문자, 그리고 !?#@%^& 등의 특수문자를 포함합니다. 그럼 한글은 어떻게 보여주죠? 네, 아스키로는 방법이 없군요. 메모리의 나머지 절반을 사용해서 표현하려고 해도 한글을 조합 하면 10,000자가 넘어갑니다. 128개로는 택도 없죠. 근데 한글만 있습니까. 한자, 일본어, 불어, 헝가리어 등등 세상엔 수십가지 종류의 문자가 존재합니다. 그래서 먼저 나온 것이 UNICODE-16입니다.

UNICODE-16

UNICODE-16의 컨셉은 아주 간단합니다. 한 문자를 1byte가 아닌 2byte로 표현하는 것이죠. 그래서 와이드 Char라고도 불립니다. 그러면 0000 0000 0000 0000 ~ 1111 1111 1111 1111 까지의 숫자를 문자와 연결 시켜 훨씬 더 많은 문자를 표현할 수 있습니다. 하지만 그만큼 한 문자를 표현하는 데에 필요한 메모리를 더 잡아먹게 되고, 거기다 기존의 ASCII 코드를 사용하던 문자를 읽을 수가 없게 되는 단점이 생깁니다. ASCII 의 두 글자를 하나로 인식해 전혀 다른 글자를 보여줄 테니까요. 또한 기존엔 1byte면 충분한 알파벳과 자주 사용하는 특수문자들도 모두 2byte를 사용해야 한다는 사실은 그다지 매력적이지 않았습니다. 컴퓨터의 메모리는 소중하니까요. 이 방식은 또 메모리의 한계를 드러냅니다. 2byte를 사용해도 표현할 수 있는 문자는 65,536 개 뿐인데, 5만 글자가 넘어가는 한자는 또 어떻게 표현해야 할까요.

UNICODE-8

그래서 나온 것이 이 인코딩 방식입니다. 아스키 코드를 1byte로 표현할 때 가장 왼쪽의 숫자가 쓰이지 않는 점을 이용한 것인데, 만약 이게 1이 되면 한 문자를 읽는데 2byte를 사용합니다. (정확한 예시는 아닙니다.)

1000 0000 0000 0000 = 가
1000 0000 0000 0001 = 나
1000 0000 0000 0010 = 다

1000 1000 0000 0000 = 쀍

그리고 가장 왼쪽의 숫자 2개가 1이면 한 문자를 표현하는데 3byte를 사용합니다.

1100 0000 0000 0000 0000 0000 = ¢
1100 0000 0000 0000 0000 0001 = ¤

이렇게라면 정말 표현할 수 있는 문자의 범위가 끝이 없지 않을까요? 또한 기존의 아스키코드도 인코딩 변환 없이 바로 읽을 수 있겠고요. 게다가 아스키 코드를 표현하는 데에는 아스키 코드를 쓰던 시절 처럼 1byte면 충분하겠네요. 참 놀라운 인코딩 방식인 것 같습니다.

참조

  • 조엘 온 소프트웨어
  • Game Engine Architecture
This post is licensed under CC BY 4.0 by the author.