문자 인코딩 (Character Encoding)
사용자가 입력한 문자나 기호들을 컴퓨터가 이용할 수 있는 신호로 만드는 것.
컴퓨터는 모든 정보를 0과 1인 바이너리, 즉 숫자로 저장한다.
그러나 우리는 문서작업, 코딩, 메시지 등 컴퓨터에서 문자를 사용하여 입력하고 저장하며 처리하고 있다.
우리가 메모장에 한글로 문자열을 입력하여 저장하게 되면 컴퓨터가 한글을 어떻게 이해할 수 있을까?
입력된 한글을 컴퓨터가 이해할 수 있는 신호로 변환하는 과정이 일어났기 때문이다.
여기서 컴퓨터가 이해할 수 있는 신호란 앞서 말한 바이너리 데이터를 의미한다.
역으로, 디코딩이란 0과 1로 구성된 바이너리 데이터를 다시 문자로 복구하는 것이다.
문자 셋 (Character Set) = 코드표
바이너리 데이터로 변환하는 인코딩과 다시 문자로 변환하는 디코딩은 미리 정해진 규칙에 의해서 수행된다.
이렇게 미리 정해진 규칙을 문자 셋이라고 하며, 초기 표준 문자열 셋은 ASCII, EBCDIC ... 이었다.
그러나 인터넷이 전세계적으로 보급되며 표현해야 할 문자가 증가하면서 문자 셋들을 표준화 할 필요성이 대두되었다.
이후 등장하게 된 것이 유니코드이다.
문자 인코딩과 문자 셋
문자 인코딩과 문자 셋은 약간 다른 개념이다.
- 문자 인코딩 : 문자를 컴퓨터가 이해할 수 있는 신호로 만드는 것
- 문자 셋 : 인코딩과 디코딩을 위해 미리 정해진 규칙
문자 인코딩이란, 컴퓨터가 이해할 수 있는 바이너리로 어떤 방법을 사용해도 상관없는 방법론이고
문자 셋이란, 문자를 숫자로 매핑해주는 표이다.
예를 들어, base64 인코딩은 문자열을 아스키코드로 인코딩한 후 다시 base64 코드표를 통해 인코딩을 수행한다.
이미 컴퓨터가 이해할 수 있는 아스키 코드로 인코딩된 문자열을 새로운 base64 코드표로 인코딩한다는 것이다.
위의 예시와 같이 인코딩이란 바이너리를 생성하기 위한 과정이라고 볼 수 있다.
또한 아스키 인코딩과 같이 문자 셋과 문자 인코딩이 동일한 경우도 있기 때문에
인코딩이 문자 셋을 포함하고 있다고 생각할 수 있다.
ASCII (American Standard Code for Information Interchange, 미국 정보 교환 표준 부호)
아스키 코드는 문자 그대로 미국에서 정의하고 있는 표준, 영문 알파벳을 사용하는 대표적인 문자 인코딩이다.
초창기 컴퓨터를 기계어만을 사용하여 개발하는것에 어려움이 있어 문자를 코드화하기 위해
아스키 코드가 탄생하게 되었고 대부분의 인코딩이 아스키에 기초하고 있다.
아스키는 7bit 인코딩으로 총 1byte(8bit)에서 7bit를 사용하여 128개의 문자를 표현할 수 있다. (0 ~ 127)
나머지 1bit는 에러 검출을 위한 Parity bit로 비워두어 총 1byte로 문자를 표현한다.
* 7개의 비트 중 1의 개수가 홀수면 1, 짝수면 0으로 설정된 Parity bit를 함께 전송함.
확장아스키코드(Extended ASCII) = ANSI 코드
앞서 말했듯이 컴퓨터와 인터넷이 전세계적으로 보급되며 영어권이 아닌 나라에서도 문자열 셋을 사용해야 했다.
그래서 기존 아스키 코드의 7bit가 아닌 8bit를 문자를 표현하는데 사용하여 총 256개의 문자를 표현할 수 있게 되었다. (128 ~ 255)
아래 사진은 메모장을 통해 알파벳과 한글 문자열들을 저장한 것이다.
HxD라는 프로그램을 통해 위의 TXT 파일이 어떻게 저장되는지 확인할 수 있다.
HxD : 바이너리 파일을 읽을 수 있는 무료 에디터 프로그램
아래 그림은 메모장에 저장된 문자열을 ANSI로 디코딩한 모습을 보여준다.
HxD를 통해 나온 결과물을 한번 살펴보자!
아스키코드표를 통해 A라는 심벌은 41이라는 HEX 값을 가짐을 확인할 수 있다.
여기서 HEX는 16진수로 결국 (4 X 16) + (1 X 1) = 65의 DEC(10진수)를 나타내는 것이다.
4bit의 값이 16개의 숫자를 나타낼 수 있기 때문에 HEX 값 하나는 4bit임을 알 수 있다.
위에서 살펴보았듯이 아스키코드는 총 8bit로 이루어져 있기 때문에 HxD에서 한칸이 아스키코드임을 알 수 있다.
결과적으로 우리가 입력한 A라는 문자열은 DEC로 65, HEX로 41이라는 숫자로 표현하기로 약속한 것이고,
컴퓨터에서는 BIN인 01000001로 저장된다는 것을 알 수 있다.
아스키코드표 : https://www.ascii-code.com/
멀티바이트 인코딩(Multibyte Encoding)
처음 멀티바이트 인코딩이 사용된 것은 CJK(Chinese-Japanese-Korean) 멀티바이트 인코딩으로
한국어, 중국어, 일본어는 문자의 수가 매우 많기 때문에 확장아스키코드 영역의 128개로도 부족했기 때문이었다.
따라서 1byte가 아닌 여러 byte를 통해 문자를 표현한 것이 멀티바이트 인코딩이다.
한국의 인코딩 방식은 여러 인코딩 방식을 거쳐왔다.
- 한글의 자음과 모음을 조합해서 표현할 수 있는 조합형 한글 인코딩
- 자음과 모음을 합쳐서 완성된 문자로 표현하는 완성형 한글 인코딩
완성형 인코딩에서는 EUC-KR : 2350자 / CP949(MS949) : 11172자 를 사용하게 되었고,
조합형 인코딩에서는 2byte 조합, 3byte 조합, N byte 조합과 같은 여러 방식을 사용하게 되었다.
많은 인코딩 방식을 사용하면서 서로 다른 인코딩 방식을 사용한 프로그램이나 문서 사이에서는 정상적으로 디코딩되지 않는 호환성 문제가 발생할 수 밖에 없었다는 것을 알 수 있다.
유니코드 (UNICODE)
멀티바이트 인코딩의 문제는 한국에 국한되는 문제가 아니었다.
한글뿐만 아니라 중국어, 일본어도 마찬가지로 각자의 언어를 표현할 수 있는 인코딩 방식과 다른 문자열 셋을 사용하기 때문에 모든 언어를 동시에 표현할 수는 없었다.
결국 전세계의 모든 문자를 하나의 문자 셋으로 표현할 수 없을까?라는 문제가 등장하게 된 것이다.
이러한 문제를 해결하기 위해 전세계적으로 사용되는 모든 문자 집합을 하나로 모아 탄생시킨 것이 유니코드이다.
유니코드의 목적은 현존하는 문자 인코딩 방법들을 모두 유니코드로 교체하려는 것이다.
유니코드는 존재하는 모든 문자들을 2byte(16bit)로 표현하려고 했으며, 이론적으로 65536개의 문자를 표현할 수 있다.
그러나 한글의 조합과 수 많은 한자들, 그리고 히라가나등, 중앙 아시아의 문자들을 2byte에는 모두 담지 못했다.
그래서 유니코드에서는 2byte를 가지는 평면을 여러개 만들어 이를 해결하고자 하였다.
평면을 나누기 위해 추가적으로 1byte를 사용할 수 있기 때문에 총 2~3byte를 통해 유니코드를 표현할 수 있다.
유니코드를 나타내는 U+와 16진수를 합쳐 U+0000에서 U+FFFF 까지 문자를 표현할 수 있으며,
앞에 평면을 위한 1byte인 U+00에서 U+FF를 추가할 수 있다. (총 256개의 평면 가능)
[예시] 1번 평면 U+01XXXX, 2번 평면 U+02XXXX 등
[0번] 유니코드 기본평면 (BMP : Basic Multilingual Plane)
앞서 말한 17개의 평면 중에 0번 평면이다.
기본평면에는 거의 모든 근대 문자와 특수 문자가 포함되어 있으며 한중일이 거의 대부분의 영역을 차지함을 확인할 수 있다.
기본 평면은 총 2byte로 U+0000 에서 U+FFFF로 표시한다.
[1 ~ 16번] 평면
1번 평면 : 보조 다국적 평면 / 옛 문자, 음악 기호, 수학 기호를 표현
2번 평면 : 보조 상형 문자 평면 / 초기 유니코드에 포함되지 않은 한중일 통합 한자를 주로 담고 있음
3번 평면 : 3차 상형문자 평면 / 갑골 문자, 금문 등의 문자와 한중일 통합 한자, 기타 옛 상형 문자를 위해 예약된 영역
4번 ~ 13번 : 미지정 평면
14번 평면 : 보조 특수 목적 평면 / 소수의 제어용 문자
15 ~ 16번 : 사용자 영역 / 특정 업체나 사용자 별로 할당하여 씀
한글 유니코드 : http://www.unicode.org/charts/PDF/UAC00.pdf
유니코드 : https://home.unicode.org/basic-info/overview/