문자 인코딩 방식
문자 인코딩 방식
이 문서에서는 문자 인코딩(Encoding) 방식의 종류와 특징에 대해서 살펴본다.
참고 영상
인코딩 vs 디코딩
인코딩(Encoding)이란 특정 방식으로 변환시키는 것을 말하고, 디코딩(Decoding)이란 인코딩 된 것을 복원하는 것을 말한다. 즉, 변환 방식에 따라 복원 방식이 결정되기 때문에 변환 방식에 대해서 종류별로 살펴보며 어떠한 발전과정을 거치게 되었는지를 파악해본다.
참조 문서
이 문서를 작성하기 위해서 참조한 사이트들을 먼저 언급한다.
문자의 변천사
컴퓨터와 문자는 애초에 관계가 없었다. 컴퓨터는 단순하게 숫자를 입력해서 계산하는 것이 목표로 시작한 기계였기 때문이다. 하지만 컴퓨터를 이용하여 다양하고 복잡한 계산들을 수행하고자 하는 목표가 생기면서부터 인간은 컴퓨터에게 글자를 알아듣게 하도록 많은 노력을 기울였다. 인코딩의 변천사를 이해하기 위해서는 컴퓨터가 어떻게 전 세계에 보급되었는가에 대해서 이해할 필요가 있다.
최초의 컴퓨터는 미국에서 만들어졌다.
유럽으로 전파되었다.
전 세계로 전파되었다.
컴퓨터에게 복잡한 계산을 명령하거나 데이터를 저장하게 하려면 글자
를 알려줘야 한다. 미국인이나 한국인 모두 자신이 사용해야 할 글자들을 컴퓨터에게 알려줘야 한다. 컴퓨터의 이용자가 어떻게 변화했느냐에 따라 인코딩의 변화도 같이 발생한다.
2진수
컴퓨터는 2진수를 사용한다. 2진수가 전기적인 신호로 의미를 전달할 수 있는 가장 간단한 방법이기 때문이다. 우리는 문자의 변천사를 이해하기 위해 어느 정도의 2진수를 다룰 줄 알아야 한다.
10진수는 각 자리가 10의 제곱수의 개수를 의미한다.
위의 식처럼 15는 10이 1개, 1이 5개 있으므로 각각의 자리는 모두 10의 거듭제곱으로 표현이 가능하다. 또한 각 자리에 표시할 수 있는 숫자는 10개이다.
2진수는 각 자리가 2의 제곱 수의 개수를 의미한다. 각 자리에는 두 개의 숫자(0, 1)를 표기할 수 있다.
각각의 10진수들은 모두 2진수로 표기될 수 있다.
1부터 10까지의 2진수 표기 전환
10진수 | 2진수 | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
1 | 00000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
2 | 00000010 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
3 | 00000011 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
4 | 00000100 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
5 | 00000101 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
6 | 00000110 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
7 | 00000111 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
8 | 00001000 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
9 | 00001001 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
10 | 00001010 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
16진수
2진수의 문제점은 값이 너무 길고 알아보기 힘들다는 것이다.
따라서 이를 좀더 보기 편하게 압축한 형태들이 8진수와 16진수이다. 8진수는 한 자리에 0~7
까지 8개를 표기할 수 있으며, 16진수는 한 자리에 0~F
까지 총 16개의 숫자를 표기할 수 있다. 이들을 이용하여 2진수를 좀 더 간결하게 표시할 수 있다.
10진수 | 2진수 | 16진수 | 10진수 | 2진수 | 16진수 |
1 | 00000001 | 0x01 | 16 | 00010000 | 0x10 |
2 | 00000010 | 0x02 | 17 | 00010001 | 0x11 |
3 | 00000011 | 0x03 | 18 | 00010010 | 0x12 |
4 | 00000100 | 0x04 | 19 | 00000011 | 0x13 |
5 | 00000101 | 0x05 | 20 | 00010100 | 0x14 |
6 | 00000110 | 0x06 | 21 | 00010101 | 0x15 |
7 | 00000111 | 0x07 | 22 | 00010110 | 0x16 |
8 | 00001000 | 0x08 | 23 | 00010111 | 0x17 |
9 | 00001001 | 0x09 | 24 | 00011000 | 0x18 |
10 | 00001010 | 0x0A | 25 | 00011001 | 0x19 |
11 | 00001011 | 0x0B | 26 | 00011010 | 0x1A |
12 | 00001100 | 0x0C | 27 | 00011011 | 0x1B |
13 | 00001101 | 0x0D | 28 | 00011100 | 0x1C |
14 | 00001110 | 0x0E | 29 | 00011101 | 0x1D |
15 | 00001111 | 0x0F | 30 | 00011110 | 0x1E |
2진수 네 자리가 16진수의 한 자리가 되며, 16진수는 다른 숫자와의 구분을 위해 일반적으로 앞에 0x
를 붙여서 표기한다.
BCD
컴퓨터는 2진수를 사용하기 때문에 10진수를 쓰는 사람 입장에서는 매우 불편하다. 16진수로 바꾸어 써도 불편한 것은 마찬가지이다. 이를 해결하기 위해 등장한 방식이 BCD 코드이며, 2진수를 10진수처럼 쓰는 것이 목적이다.
종류 | 천 | 백 | 십 | 일 |
10진수 | 1 | 2 | 3 | 4 |
BCD | 0001 | 0010 | 0011 | 0100 |
BCD 코드의 특징은 2진수처럼 보이긴 하지만 10진수의 각각의 자리를 4bit의 2진수로 표기하여 값을 나타낸다. 자리 별로 변환하였기 때문에 4자리의 2진수만 읽을 줄 알면 된다는 특징이 있다.
ASCII
BCD 코드는 숫자를 전달하기 위해 만들어졌으나, 시간이 지남에 따라 글자도 전달할 필요성이 생기게 된다. 이를 위해 만들어진 코드가 ASCII(Ameracan Standard Code for Information Interchange, 미국 정보 교환 표준 부호)이다. ASCII는 미국 국립 표준 협회(ANSI)에서 제정한 표준이며, 7bit
를 기준으로 설계되었다.
우리가 알고 있기로 1byte는 8bit이지만, 이 당시에는 명확한 기준이 없이 서로 다른 크기를 1byte로 정의하던 시기였다. ASCII 코드는 다음 특징을 가진다.
ASCII의 A는 American이다.
American이 필요한 글자는 7bit에 모두 들어간다.
알파벳 소문자 26개
알파벳 대문자 26개
숫자 10개
제어 문자 32개
기타 기호 등
ASCII 코드표는 검색을 통해 쉽게 찾을 수 있다. 알아야 할 중요한 값들만 살펴본다.
글자 | 값 |
\t | 9 |
\n | 10 |
SPACE | 32 |
0 | 48 |
A | 65 |
a | 97 |
확장 ASCII
ASCII 만으로는 유럽의 글자들을 표시하기에 부족했다. 따라서 7bit로 구성된 ASCII에 오류검사용 1bit까지 포함시켜 256개로 확장시켜 사용하게 되는데 이를 확장 ASCII 라고 부른다. 이 방식을 ISO와 IEC의 공동 표준으로 제정하였으며, 각 지역별로 표현하는 추가적인 기호가 달라 총 16개의 세부 표준이 제정되었다. 위키백과 ISO-8859
ISO/IEC 8859-1 : 라틴-1/서유럽 (대부분의 유럽언어 지원, HTML 표준 방식)
ISO/IEC 8859-2 : 라틴-2/중앙 유럽 (로마 문자를 쓰는 중앙유럽과 동유럽)
ISO/IEC 8859-3 : 라틴-3/남유럽 (몰타어, 터키어, 에스페란토)
ISO/IEC 8859-4 : 라틴-4/북유럽 (에스토니아어, 라트비아어, 리투아니아어, 그린란드어, 사미어)
ISO/IEC 8859-5 : 라틴/키릴 (키릴 문자를 쓰는 대부분의 슬라브어)
ISO/IEC 8859-6 : 라틴/아랍
ISO/IEC 8859-7 : 라틴/그리스
ISO/IEC 8859-8 : 라틴/히브리
ISO/IEC 8859-9 : 라틴-5/터키
ISO/IEC 8859-10 : 라틴-6/노르딕
ISO/IEC 8859-11 : 라틴/타이
ISO/IEC 8859-12 : 라틴/데바나가리 (1997년 폐기)ISO/IEC 8859-13 : 라틴-7/발트해 연안
ISO/IEC 8859-14 : 라틴-8/켈트
ISO/IEC 8859-15 : 라틴-9/서유럽
ISO/IEC 8859-16 : 라틴-10/남동유럽
한글
확장 ASCII로는 한글을 표시할 수 없다. 이것은 미국/유럽권역이 아닌 다른 나라들 모두 공통적으로 해당되는 사항이다. 따라서 각각의 나라에 맞게 표준들이 제정되어 사용되게 된다. 여기서 중요한 것은 비 영어/유럽권역에서는 1byte로 글자가 다 표시될 수 없다는 점이다. 1byte는 최대 256개까지밖에 표현할 수 없기 때문에 비영어권 국가들은 2byte를 조합하여 각각의 표현 방식을 제정하게 된다.
완성형 한글과 조합형 한글
한글은 구조적 특징으로 인해 두 가지 방식으로 인코딩이 개발된다.
완성형 한글 - 영문처럼 한글 1글자에 번호를 부여하여 관리하는 인코딩 방식
조합형 한글 - 초성, 중성, 종성을 각각 번호를 부여하여 조합할 수 있도록 만들어진 인코딩 방식
표준이 제정되기 전까지 다양한 형태들의 조합형과 완성형 인코딩 방식들이 개발되고 사라졌다. 한글의 구조로 봤을 경우 조합형 방식이 훨씬 더 좋아보이지만 한글이 아닌 다른 언어의 글자 인코딩 방식과 호환이 되지 않는 문제 때문에 한국에서의 표준은 완성형 한글로 정해지게 되었다.
KS X 1001 (구 KSC5601)
92년 한국 공업 표준(Korea Industrial Standard)에서 정보 처리 분야(C)의 5601번 표준안으로 제정된 완성형 한글의 국가 표준
이다. 현재는 KS X 1001로 명칭이 변경되었다. 완성형 한글이란 한글을 알파벳처럼 하나의 완전한 글자로 보고 순서대로 번호를 붙였다는 것을 의미한다. 이 방식에서는 2,350
자의 한글에 번호를 붙여 사용 가능하도록 제정하였다. 여기에는 ASCII가 포함되지 않는다. 정보통신기술용어해설 보기
KS X 1003(구 KSC5636)
한국 공업 표준(Korea Industrial Standard)에서 정보 처리 분야(C)의 5636번 표준안으로 제정된 영문 표기 표준
이다. 현재는 KS X 1003으로 명칭이 변경되었다. ASCII는 여기에 포함되어 있다. ASCII 코드와 딱 한 가지만 빼고 동일하며, 그 한가지가 역슬래시이다. 편집기에서 글꼴에 따라 \
혹은 ₩
로 나오는 이유는 ASCII와 KS X 1003의 차이 때문이다.
EUC-KR
EUC(Extended Unix Code)는 확장 유닉스 코드이며 EUC-KR
은 한국어를 위한 확장 코드이다. EUC-KR
은 KS X 1001 (#ksc5601)과 KS X 1003 (#ksc5636)을 혼합한 형태를 말한다. ASCII는 1byte, 한글 등은 2byte로 표현한다. 과거에는 대부분 EUC-KR
을 사용했다. 하지만 간혹 표시가 안되는 글자들이 존재했는데 다음과 같다.
똠방각하 : 1990년 방영된 MBC 월화 드라마
롹앤롤
똠양꿍
외래어 표기가 늘어나고 신조어들이 늘어나면서 EUC-KR을 통해 표현되지 않는 글자들이 계속해서 발생하게 되고, 이는 새로운 인코딩 방식이 등장하는 계기가 된다.
CP949(MS949)
Code Page 949, 줄여서 CP949
라고 부른다. 마이크로소프트(Microsoft)에서 윈도우를 위해 독자적으로 제정한 규격으로 11,172자의 한글을 표현한다. 즉, 모든 한글 글자에 번호를 부여했다고 보면 된다. 한글의 첫글자는 가
이고, 마지막 글자는 힣
이다. 기존 EUC-KR에 8,822글자를 추가하여 모든 한글이 표현 가능하도록 구현되어 있다. 윈도우의 기본 한글 표현 방식이며 MS949라고 부르기도 한다. 윈도우 98부터 탑재되었다.
Code Page 949(CP949)는 다음 두 가지로 구분되는 경우가 있다.
IBM에서 만든 코드 페이지 949
MS에서 만든 코드 페이지 949
IBM에서 만든 코드 페이지 949가 시기적으로 앞이기 때문에 자바의 경우 CP949라 하면 IBM의 코드페이지 949를 말한다. 따라서 엄격한 구분이 필요한 경우 CP949와 MS949를 혼용하지 말아야 한다.
유니코드(Unicode)
전 세계적으로 다양한 글꼴들이 개발되었으나 문제는 호환이 되지 않는다는 것이다. 따라서 글로벌 애플리케이션을 개발하는데 있어서 많은 어려움이 있었다. 이를 해결하기 위해 유니코드 컨소시엄(Unicode Consortium, Unicode. Inc.) 단체를 설립하고 전 세계의 모든 글자를 통합하기 위한 작업을 시작하게 된다.
유니코드 평면(Unicode Plane)
전 세계의 글자를 통합하려 할 때 예상 가능한 문제들은 다음과 같다.
자주 사용하는 글자들을 최우선으로 접근할 수 있어야 한다
옛 글자들도 필요하다면 사용할 수 있도록 접근할 수 있어야 한다
따라서 글자들을 2byte(65,536글자)씩 나눠서 하나의 평면(Plane)으로 정의하였다.
Plane 0 - 기본 다국어 평면(BMP, Basic Multilingual Plane). 가장 최신의 자주 사용하는 글자 평면
Plane 1 - 보조 다국어 평면(SMP, Supplementary Multilingual Plane). 보조적으로 필요한 글자 평면
Plane 2 - 보조 표의문자 평면(SIP, Supplementary Ideographic Plane). 한자 전용 평면
Plane 3 - 3차 표의문자 평면(TIP, Tertiary Ideographic Plane). 고대 중국 문자 평면
Plane 4 ~ Plane 13 (사용 안함)
Plane 14 - 보조 특수 목적 평면(SSP, Supplementary Special-purpose Plane). 제어용 문자 평면
Plane 15, 16 - 사용자 자유 영역(PUA, Private User Area). 사용자가 임의로 할당하는 영역. 호환불가
현재 평면은 총 17개가 존재하며 앞으로 늘어날 가능성도 있다. 향후 계획은 유니코드 홈페이지 로드맵에서 확인할 수 있다.
유니코드 평면 그룹
유니코드 평면 256개를 묶어서 하나의 평면 그룹으로 정의할 수 있다. 현재는 17개의 평면밖에 존재하지 않기 때문에 유니코드는 하나의 평면 그룹으로 구성되어 있다고 볼 수 있다.
UCS-2
국제 문자 세트(UCS, Universal Character Set, 범용 문자 집합) 중 하나로 ISO/IEC 10646 표준에 정의되어 있다. 유니코드 평면 중에서 첫 번째 평면인 BMP만을 0부터 65535까지 번호를 부여하여 사용할 수 있도록 정의한 규격이다.
UCS-4
국제 문자 세트(UCS, Universal Character Set, 범용 문자 집합) 중 하나로 ISO/IEC 10646 표준에 정의되어 있다. 총 128개의 평면 그룹을 사용 범위로 정의한 규격이다.
2020년 개정판에서 UTF-32의 대체어로 정의되어 더이상 사용하지 않는다는 설명이 첨부되어 있다.
ISO/IEC 10646:2020(en)
10.4 UTF-32UTF-32 is the UCS encoding form that assigns each UCS scalar value to a single unsigned 32-bit code unit.
NOTE Former editions of this document included “UCS-4” as an alternate term synonymous with “UTF-32”. Use of the term “UCS-4” to refer to this encoding form is deprecated.
참고 이 문서의 이전 버전에는 "UTF-32"와 동의어인 대체 용어로 "UCS-4"가 포함되어 있습니다. 이 인코딩 형식을 참조하기 위해 "UCS-4"라는 용어를 사용하는 것은 더 이상 사용되지 않습니다.
Because surrogate code points are not UCS scalar values, UTF-32 code units in the range 0000 D800 - 0000 DFFF are ill-formed.
UTF-8
Code Page 65001이라고도 한다. 한 글자가 1byte부터 4byte까지의 값을 가질 수 있는 가변 형태이며, ASCII와 100% 호환된다. 실제로 6byte 까지 쓸 수 있지만 다른 방식들과의 호환을 위해 4byte까지만 사용한다. 이러한 장점으로 인해 인터넷 사이트에서 가장 많이 쓰이는 인코딩(문자 변환) 방식이며 기존의 ISO-8859
로 작성된 페이지들을 깨짐 없이 그대로 읽을 수 있다는 특징이 있다. 즉, 비영어권에서 사용할 수 있는 가장 이상적인 형태의 인코딩 방식이라고 볼 수 있다.
UTF-8 이외에도 UTF-16, UTF-32 등 다양한 방식이 있는데 UTF-8이 가장 널리 쓰인다. UTF-16과 UTF-32의 경우 엔디언(Endianess) 방식 차이로 인하여 해석의 문제가 생길 수 있기 때문에 혼동이 적은 UTF-8을 선호하는 편이다. 물론 UTF-16 등도 OS 커널 등 핵심 도구들에서 사용된다.
UTF-8 체계에서 한글은 3byte 형태로 표기된다. 이유는 한글의 첫 글자인 가와 마지막 글자인 힣이 각각 44032, 55203이라는 값을 가져 3byte 표기범위 내에 위치하기 때문이다. 만약 받침이 없는 경우라면 채움 문자로 대체되어 동일하게 3바이트 처리된다. 초성
, 중성
, 종성
으로 나뉘어 각각 1byte씩을 차지하게 되며, 분리와 결합을 위한 공식이 존재한다. 이로 인해 완성형 인코딩(EUC-KR, CP949) 등에서 발생하는 한글 깨짐 및 복원 작업이 필요없다. 유일한 단점이라고 볼 수 있는 것이 한글 한 글자를 저장하기 위해서 완성형 인코딩보다 1byte를 더 필요로 한다는 점이다.(완성형 인코딩은 2byte를 사용한다)
현재 가면 갈 수록 모든 문자체계가 UTF-8
로 대동단결하는 분위기이며, 대부분의 대형 서비스들이 채택하여 사용하고 있기 때문에 의심의 여지 없이 설정하여 사용해야 한다. MS계열의 애플리케이션에서도 호환 가능한 수준에서 UTF-8
을 채택하고 있다.
Last updated