dev-sohee 님의 블로그

문자 인코딩의 진화, ASCII, 유니코드, UTF-8, UTF-16 본문

CS

문자 인코딩의 진화, ASCII, 유니코드, UTF-8, UTF-16

dev-sohee 2024. 7. 19. 18:54

혹시 컴퓨터가 어떻게 인간의 언어를 알아듣고 출력하는지 궁금하지 않으신가요? 

컴퓨터는 분명 '0'과 '1'만 알아 듣는다고 했는데 개발자는 영어로 개발을 하고 화면에는 영어, 중국어, 한국어 등 다양한 언어들이 출력되는 프로그램을 만들 수 있습니다. 이것을 가능하게 하는 것이 바로 문자 인코딩입니다.

오늘은 문자 인코딩 방식 중 ASCII, 유니코드, UTF-8, UTF-16에 대해 알아보겠습니다.

* ASCII(American Standard Code for Information Interchange)
* 유니코드
* UTF-8(Universal Coded Character Set Transformation Format 8-bit)
* UTF-16(16-bit Unicode Transformation Format)

 

문자 인코딩이란?

: 사용자가 입력한 문자나 기호들을 컴퓨터가 이용할 수 있는 신호로 만드는 것

문자 인코딩은 사용자가 입력한 문자나 기호들을 컴퓨터가 이용할 수 있는 신호로 만드는 것입니다. 신호를 입력하는 인코딩과 문자를 해독하는 디코딩을 하기 위해선 미리 정해진 기준을 바탕으로 입력과 해독이 처리되어야 하는데, 이를 문자열 세트라고 합니다. 초기 문자열 세트는 대표적으로 ASCII가 있었으나, 인터넷이 전세계에 보급되며 표현해야 할 문자가 증가하면서 ASCII의 한계를 보완하기 위해 유니코드가 등장하게 되었습니다.

 

# ASCII

문자표란 숫자와 문자를 1대1로 매칭시킨 표입니다. 아스키코드는 1byte , 즉 8bit의 데이터를 사용합니다. 

출처_https://velog.io

 

예를 들어, 알파벳 'A'는 아스키코드로 65입니다. 그런데 여기서 이상한 점이 있습니다. 아스키코드는 8bit의 데이터를 사용한다고 했는데 표의 이진수는 일곱자리입니다. 남은 한자리는 패리티 비트(parity bit)라고 부르는데, 데이터의 에러를 탐지하기 위해 사용됩니다. 일곱자리의 이진수에서 '1'이 홀수개라면 끝에 1을, '1'이 짝수개라면 끝에 0을 덧붙입니다.

아주 정밀하진 않지만 패리티 bit 를 이용해 어느 정도의 에러를 탐지할 수 있습니다. 따라서, 패리티 비트를 제외하면 아스키 코드는 총 7자리의 이진수를 문자로 내타낼 수 있기 때문에 총 2^7 = 128개의 문자를 나타낼 수 있습니다.

하지만 아스키코드에는 아주 큰 단점이 있습니다. 바로 영어만 표현할 수 있다는 것입니다. 영어권 사람들만 주로 컴퓨터를 이용하던 시절엔 문제가 없었지만 컴퓨터가 전세계적으로 보급되면서 문자가 깨지는 현상이 발생하고 '걁궬뷀뒐' 같은 문자들이 표현되기 시작했습니다.

 

# 유니코드

그래서 전 세계 언어의 문자를 정의하기 위한 국제 표준 코드인 유니코드가 등장하게 됐습니다. 1byte로는 부족했으니 용량을 크게 확장한 2byte (2^16 = 65,536)를 사용하게 됐습니다. 처음에는 65,536개에 온 세상 문자를 모두 담을 수 있을 것이라 생각했지만 쓰지 않는 고어, 토속어 같은 모든 문자를 담으려다 보니 이마저도 부족했습니다. 그래서 32bit로 늘리려고 시도했으나 32bit는 문자 하나를 표현하기에는 메모리를 너무 많이 차지했습니다.

 

# UTF-16

그래서 16bit를 유지하는 대신 언어판을 늘리기로 했습니다. 언어판을 17개까지 늘려 총 17 x 65536가지의 문자 표현이 가능해졌습니다.

출처_https://lordofkangs.tistory.com

 

UCS-2 (Universal Character Set 2-byte)는 유니코드 표준의 한 형태로, 각 문자를 2byte로 인코딩하는 방식입니다. UCS-2는 유니코드의 초창기 버전으로, 65,536개의 고유한 문자를 표현할 수 있습니다.

가장 맨 앞에 있는 언어판은 가장 자주 사용되는 기본 언어판(BMP, Basic multilingual plane)입니다. 우리 한글도 이 곳에 포함됩니다. 기본 언어판에 있는 문자들은 16bit로 표현이 가능합니다. 그러나 기본 언어판에 없는 문자들은 다른 언어판에서 찾아야 합니다. 그러므로 다른 언어판을 가리키는 메타데이터가 포함되어야 하는데, 이때 데이터의 길이가 16bit + α 로 가변적이게 된다는 문제점이 발생합니다.

이렇게 UCS-2 문자표를 활용하여, 기본 문자들은 16bit를 사용하고 그 외 문자들은 가변적으로 변하는 방식을 UTF-16 인코딩 방식이라고 합니다. UTF-16은 영어와 숫자를 표현하는데 16bit나 사용합니다. 아스키 코드로는 7bit면 표현이 가능했으므로 8bit는 아무 의미 없이 공간만 차지한다는 뜻입니다. 그런데 컴퓨터에서 사용되는 대부분의 언어는 영어와 숫자입니다. 그러므로 UTF-16은 굉장히 비효율적으로 공간을 차지한다고 할 수 있습니다.

 

# UTF-8

그래서 공간의 효율성을 위해 7bit로 표현 가능한 문자들은 7bit로 표현하기 위해서 UTF-8이 등장합니다.

UTF-8을 인코딩하기 위한 약속은 다음과 같습니다.

1) 1바이트만 쓰는 경우 - 데이터 앞에 0을 붙인다(ASCII와 같은 방식으로 표현)

2) 2바이트만 쓰는 경우 - 데이터 앞에 110을 붙인다

3) 3바이트만 쓰는 경우 - 데이터 앞에 1110을 붙인다

4) 4바이트만 쓰는 경우 - 데이터 앞에 11110을 붙인다

5) 2, 3, 4번의 경우 첫 번째 바이트 이후 바이트에는 앞에 10을 붙인다

예시) 11110000 10011111 10001101 10001110
--> 11110이 앞에 오고 후행 바이트들이 10으로 시작하므로 4바이트를 쓰는 경우다.
밑줄 친 부분을 제외하고 남은 데이터들을 합치면 000 011111 001101 001110 이 된다.
이를 16진수로 변환하면 1F34E이 된다.
U+01F34E는 🍎︎(사과 이모티콘)이다.

 

정리하면, ASCII와 유니코드는 문 자와 코드가 1:1매핑되어 있는 ‘코드표'이고, UTF는 유니코드를 인코딩하는 방식입니다. 인코딩 방식은 상황에 따라 잘 선택해야 합니다. ASCII 코드 문자 안에서 주로 문자가 사용된다면 UTF-8 인코딩 방식이 유리하지만  ASCII 코드 문자를 벗어나는 문자를 사용하면 UTF-16이 유리할 수 있습니다. 

'CS' 카테고리의 다른 글

Git Flow: 소프트웨어 개발의 새로운 표준  (2) 2024.10.05