문자의 내부 표현

컴퓨터는 데이터를 2진수(비트)로만 처리할 수 있기 때문에, 문자 역시 2진수로 표현돼야 합니다.
하지만 영문 알파벳뿐 아니라 한글, 한자 등 다양한 문자를 저장하려면 각 문자를 구분할 수 있는 규칙이 필요합니다.
이를 위해 문자마다 고유한 숫자를 부여하는 방식이 사용됩니다.

이처럼 문자에 고유한 숫자를 부여하여 표현하는 체계를 문자 집합(Character Set)이라고 합니다.

문자 집합은 각 문자를 숫자로 매핑하는 규칙이며, 실제 메모리에 저장하기 위해서는 이를 바이트 형태로 변환하는 과정이 필요합니다.
이 과정을 인코딩(Encoding)이라고 하며, 반대로 바이트 데이터를 문자로 해석하는 과정을(Decoding)이라고 합니다.

문자 집합

문자 집합(Character Set)은 어떤 문자들이 존재하는지와 각 문자에 대응되는 고유한 코드 포인트를 정의한 것입니다.

대표적으로 ASCII, Unicode와 같은 문자 집합이 있습니다.

인코딩

인코딩(Encoding)은 문자 집합에서 정의된 코드 포인트를 실제 메모리에 저장하기 위해 바이트 형태로 변환하는 방식입니다.

대표적인 인코딩으로 UTF-8, UTF-16, EUC-KR, CP949등이 있습니다.

다음 사이트에서 다양한 인코딩과 디코딩을 경험해볼 수 있습니다.
DenCode

디코딩

디코딩(Decoding)은 바이트 데이터를 다시 문자로 해석하는 과정입니다.

인코딩 방식과 디코딩 방식이 일치하지 않으면 문자가 깨지는 문제가 발생할 수 있습니다.

ASCII

ASCII(아스키 코드/ASCII: American Standard Code for information Interchange Code)는 7비트 기반의 문자 집합이며, 이를 저장하기 위해 보통 1바이트를 사용하는 인코딩이 함께 사용됐습니다.

초창기 컴퓨터에서 사용하던 문자 집합 중 하나로, UTF-8 등에서 기본 영역으로 포함되어 여전히 사용됩니다.

33개의 제어 문자와 공백 포함 95개의 출력 가능한 문자로 총 128개의 문자를 표현할 수 있습니다.

초기 통신 시스템에서는 8번째 비트를 패리티 비트(Parity Bit)로 사용하여, 전송 오류를 검출하는 데 활용했습니다.
맨 앞 비트에 0을 붙이고 이어서 7비트가 사용되는 식의 인코딩이 일반적입니다.

ASCII_CODE

출력 가능한 문자는 52개의 대소문자 알파벳과 10개의 숫자, 1개의 공백문자, 32개의 특수문자로 구성됩니다.
제어문자들은 이제 대부분 사용되지 않습니다.

예를 들어, 아스키 코드에 의하면 대문자 ‘A’는 10진수로 65이고 저장공간에는 2진수로 01000001가 저장됩니다.

ANSI 코드

ANSI 인코딩은 공식적인 표준 명칭이 아니라, 일반적으로 Windows에서 사용하는 코드 페이지 기반 문자 인코딩을 통칭하는 비공식 용어입니다.

코드 페이지(CodePage)는 특정 언어를 지원하기 위해 문자와 코드값을 매핑한 테이블이며, 어떤 코드 페이지를 사용하느냐에 따라 동일한 바이트 값도 다른 문자로 해석될 수 있습니다.

ASCII 이후 다양한 확장 문자 표현을 위해 등장한 것으로, 코드 페이지에 따라 1바이트 또는 다바이트 문자를 사용할 수 있습니다.

EUC-KR

ASCII는 숫자와 알파벳 등 일부 문자만 표현할 수 있었기 때문에 각 언어권에서는 자국 문자를 표현하기 위한 다양한 인코딩 방식을 만들었습니다.
그 중 EUC-KR은 한국어를 표현하기 위해 만들어진 문자 인코딩 방식입니다.

EUC-KR은 EUC(Extended Unix Code) 계열로, 유닉스 환경에서 주로 사용된 인코딩입니다.

ASCII 문자는 1바이트, 한글과 같은 문자는 2바이트로 표현하는 멀티바이트 인코딩 방식입니다.
UTF-8처럼 복잡하게 길이가 변하지 않고 오직 1 또는 2바이트의 길이만 사용하여 구조가 상대적으로 단순합니다.

또한 완성형 인코딩 방식을 사용하며, 이는 초성, 중성, 종성을 조합하는 것이 아니라 , 등과 같이 완성된 문자 하나에 각각의 코드가 할당되는 방식입니다.

아래의 이미지는 EUC-KR 문자열 표입니다.

EUC-KR_CharacterCodeTable

한글 b0a1로 대응됩니다.

코드표에는 위와같은 한글뿐만이 아니라 특수 기호, 영어, 일부 한자 등을 포함하고 있습니다.

언어권마다 서로 다른 인코딩을 사용할 경우, 같은 바이트 데이터를 다르게 해석하게 되어 문자가 깨지는 문제가 발생할 수 있고, EUC-KR에 정의되지 않은 다른 언어를 동시에 표현하기 어려운 한계도 존재합니다.

또 다른 문제로 약 2,350자의 한글을 지원하는데, 모든 한글을 표현하기에는 부족하다는 문제가 있습니다.

이런 문제를 해결하기 위해 EUC-KR을 확장한 CP949가 등장했으며, 이후에 전 세계 모든 문자를 통합적으로 표현하기 위한 유니코드가 등장했습니다.

CP949

마이크로소프트에서 Windows 환경에서 한글 지원을 위해 만들어진 인코딩으로, EUC-KR을 확장한 코드 페이지 기반 인코딩 방식입니다.
CP949는 한국어 코드 페이지 번호를 의미하며, MS949라고도 부릅니다.

UEC-KR과 같이 ASCII 문자는 1바이트, 한글 및 확장 문자는 2바이트로 표현됩니다.

EUC-KR이 많은 한글 단어를 표현하지 못한 문제를 보완하기 위해, 사용되지 않던 바이트 조합을 활용하여 더 많은 한글 문자를 표현할 수 있도록 확장되었습니다.

CP949는 EUC-KR을 포함하여 EUC-KR로 인코딩된 데이터를 문제없이 처리할 수 있지만, 반대의 경우 일부 문자가 표현되지 않습니다.

윈도우 메모장에서 인코딩 방식을 ANSI로 선택할 경우, 시스템 로컬에 따라 코드 페이지가 결정되어 한국어 환경에서 CP949로 저장됩니다.

유니코드(UniCode)

전 세계의 모든 문자를 컴퓨터에서 일관되게 표현할 수 있는 표준 문자 코드표로 컴퓨터간 문자 데이터 교환을 원활하게 하기 위해 유니코드 협회가 제정하였습니다.

유니코드는 각 문자에 코드 포인트(Code Point) 단위로 관리하며, 관련 문자들을 묶어 블록(Block)이라는 단위로 구성합니다.
또한, 코드 포인트 공간을 평면(Plane)이라는 단위로 나누어 총 17개의 평면(0 ~ 16)을 가지고, 각 평면은 65,536개의 코드 포인트를 가집니다.

코드 포인트는 문자의 번호로서 U+0000부터 U+10FFFF까지 정의되어 있으며, 총 약 111만 개의 문자를 표현할 수 있습니다.
여기서 U+는 유니코드 코드 포인트임을 나타내는 접두어이며, 그 다음 문자들은 16진수 숫자를 나타냅니다.

블록은 연속된 코드 포인트 범위를 기준으로 유사한 문자들을 묶어놓은 구간이며, 특정 언어나 문자 체계를 중심으로 구성되는 경우가 많지만 반드시 1:1 대응되지는 않습니다.

유니코드는 기존의 ASCII를 포함합니다.
예를 들어, A는 U+0041의 코드 포인트를 가집니다.

현대 가장 많이 사용되는 표준 문자 집합입니다.

유니코드의 인코딩 방식으로 UTF(Universal Transformation Format)-8, UTF-16 UTF-32 등이 있습니다.

UTF-8

UTF-8은 가변 길이 인코딩(멀티바이트)으로 1 ~ 4바이트까지 문자를 표현할 수 있습니다.
멀티바이트란 표현해야하는 문자에 따라 글자 크기를 가변으로 변경하여 사용하는 것을 말합니다.

코드 포인트 범위에 따라 바이트 수가 결정되며, 기존 ASCII는 U+0000 부터 결정되어 1바이트가 사용됩니다.

웹에서 가장 널리 사용되는 인코딩 방식입니다.

UTF-16

UTF-16은 유니코드 문자를 2바이트 또는 4바이트로 표현하는 가변 길이 인코딩 방식입니다.

BMP(Basic Multilingual Plane)에 속한 문자를 2바이트로 표현하며, 이 외에는 Surrogate Pair를 사용하여 4바이트로 표현합니다.
BMP에는 한글, 영어, 한자 등의 문자가 포함 되어있습니다.

2바이트 단위를 사용하기 때문에 바이트 순서(Byte Ordering)의 영향을 받으며, 이를 구분하기 위해 BOM(Byte Order Mark)을 사용하기도 합니다.
Little Endian을 사용한 경우 UTF-16LE, Big Endian을 사용한 경우 UTF-16BE로 구분됩니다.

UTF-32

UTF-32은 모든 문자를 4byte로 표현하는 고정 길이 인코딩 방식입니다.

모든 코드 포인트를 동일한 크기로 저장하기 때문에 랜덤 접근이 가능하다는 장점을 가집니다.
또한, 구현이 상대적으로 단순합니다.

메모리 사용량이 가장 크다는 단점을 가집니다.

ComputerScience 카테고리 내 다른 글 보러가기

댓글남기기