본문 바로가기
IT

ASCII Code, Unicode, encode, decode (1편)

by Redking

시작하기 전에

  1. 컴퓨터의 기본 저장 단위는 바이트(byte)이다.
  2. 1바이트(byte)는 8비트(bit)이다.
  3. 1byte에는 2의 8승에 해당하는 256개의 고유한 값을 저장할 수 있다.
  4. 문자나 기호들의 집합을 컴퓨터에서 저장하거나, 통신 목적으로 사용할 경우에는 부호로 바꾸어야 한다.

이를 **'문자 인코딩(encoding)' 또는 '부호화'**라고 하며 부호화된 문자를 복원하는 것을 '복호화'라고 한다.

ASCII Code

ASCII(아스키)는 American Standard Code for Information Interchange의 약자로써, ANSI(미국표준협회)에서 만든 표준 코드 체계다.

ASCII Code를 만든 이유는, 컴퓨터는 1과 0 이 두 수로 밖에 연산을 할 수 없으므로 문자도 숫자로 기억하는데 이때, 어떤 수를 어떤 문자를 대응시키는가에 따라 다양한 인코딩 방식이 있고 표준없이 여러 인코딩 방식을 사용하다보니 호환 등의 여러 문제가 발생하여 만든게 ASCII Code다.

물론 처음 만들 때 영어권에서 만든데다가 다른 나라 문자는 신경 쓸 필요(혹은 여력)가 없어 영 소문자, 영 대문자, 숫자 등만 표현이 가능한데 요즘 같은 국제화 시대에는 모든 언어를 표현해야 하므로 후에 보완해서 나온 코드 체계가 유니코드다.

ASCII Code(아스키 코드)는 0번부터 127번까지만 사용한다. 127번 이후 코드를 사용했던 적도 있었지만 이는 표준이 아니며 운영체제 마다 다른 문자(코드)를 배치했기 때문에 호환이 되지 않는다. 윈도우즈 운영체제는 현재 128번 부터 255번 사이에 포함된 문자를 출력 하려는 시도에 대해 ?(물음표)를 출력해서 사용하면 안된다는 것을 알 수 있다.

 

아스키 코드는 1바이트의 용량을 가지고 있다. 그러나 아스키 코드가 256개가 아닌 128개인 이유는 1비트를 통신 에러 검출을 위해 사용하기 때 사용하기 때문이고 통신 에러 검출을 위한 비트를 Parity Bit라고 한다. 과거에는 이를 사용했으나, 현재는 쓰이지 않으면서, 문자를 표현한 7비트 앞에 0을 집어넣는 방식으로 사용하고 있습니다.

 

※ 제어 문자 0~31, 127

아스키 코드 테이블에서 처음 0부터 32까지와 127은 제어 문자라고 해서 화면에 출력하거나 인쇄 할 수 없으며, 프린터와 같은 주변 장치를 제어하거나 전송, 제어를 위해 사용된다.

 

※ 출력 가능 문자 32~126

32부터 126번 까지는 구두점, 숫자, 영 대문자, 영 소문자 등 출력 가능한 문자 및 문장 부호를 나타내며, 이 문자들은 키보드에서 대부분 찾을 수 있다.

 

Unicode

전 세계의 문자를 컴퓨터에서 일관되게 표한하고 다룰 수 있도록 설계되었으며 아스키 코드가 1바이트를 사용해 문자를 저장 하던 것과 다르게 최대 21비트를 사용하는데 32비트중 11비트는 의미없이 남아버리는 것이다.

하지만 이러한 낭비가 발생함에도 불구하고, 이 인코딩 방식은 고정길이를 사용하여 가변길이의 부호를 해석할 필요가 없어져서 데이터 처리가 단순해진다. 현재의 컴퓨터 환경에서 4바이트를 데이터 블록의 단위로 사용하는 시스템도 존재하기 때문에 1바이트 2바이트로 처리하는 것보다 성능에서 우위를 보일 수 있다.

문자배정 방식

초기에 유니코드는 0x0000부터 0xFFFF 까지 2^16(65536개)에 모든 문자를 집어넣었습니다.

하지만 2^16개의 자리로도 부족해지자 0x0000부터 0xFFFF까지 문자를 배정해놓은 세트를 총 17개로 늘리게 됩니다.

이 세트들을 유니코드에서는 “평면”이라고 부르고, 앞에서부터 0번 ~ 16번 까지 번호를 붙여놓았습니다.

이 평면중에서 현대에서 쓰이는 문자들을 모두 0번 평면에 몰아넣었는데 이 평면을 기본 다국어 평면(BMP, Basic multilingual plane)라고 합니다.

( 현재 사용되고 있는 평면은 0~2번과 14~16번의 6개 평면입니다. )

유니코드 평면이란 유니코드 전체를 논리적으로 나눈 구획을 말한다. 0번(다국어 기본 평면)에서부터 16번까지 모두 17개로 나뉘며, 각 평면은 65536개(2^16승)의 코드로 구성된다.

유니코드를 표시하는 방법 : U+

유니코드에서는 모든 평면이 0x0000부터 0xFFFF의 값을 가지고 있기 때문에 문자끼리 겹치는 현상이 발생했습니다.

예를 들어서 0xB000은 0번 평면에서는 한글 “뀀”이지만 1번 평면에서는

라는 글자가 됩니다.

이런 문제를 해결하기 위해서 유니코드에서는 U+ 라는 기호에 평면 숫자를 붙이는 방식을 사용했습니다. ( 단, 0번 평면의 경우는 숫자를 붙이는 것을 생략했습니다.

ex) 한글 “뀀”은 0번 평면에 있으니 아무것도 붙이지 않고 U+B000라고 표시하면 됩니다.

ex2)

1번 평면에 있으니 U+1을 붙여서 U+1B000이 됩니다.

유니코드 인코딩 종류

유니코드로는 세상에 존재하는 거의 모든 문자를 표현할 수 있지만, 그만큼 바이트를 많이 사용하기 때문에 용량이 크다는 문제가 있습니다.

또, 첫 번째로 평면을 표시하는 숫자를 앞에 붙여야 하기 때문에 문자를 표시하는 바이트 외에 자리가 더 필요한 상황이 됩니다.

그런 문제를 해결하기 위해서 유니코드는 많은 인코딩 방식을 가지고 있습니다.

유니코드의 인코딩 방식으로는 UCS-2, UCS-4, 그리고 UTF-8, UTF-16, UTF-32 등이 있습니다.

 

ex) 0xAC00은 빅엔디안을 사용하는 시스템에서는 한글 “가”가 되지만, 리틀 엔디안(0x00AC로 바뀜)을 사용하는 시스템에서는 ¬ 라는 제어문자가 됩니다.

이를 해결하기 위해서 2바이트인 BOM(Byte Order Mark)을 유니코드 파일이 시작되는 첫 부분에 명시해서 문자열이 어떤 엔디안 방식을 사용하는지 명시하도록 했습니다.

바이트 순서 표식(BOM)의 종류

ex) 한글 “가”는 BOM이 0xFEFF라면(빅엔디안) 0x0048이 되고 BOM이 0xFFFE라면(리틀엔디안)  0x4800으로 저장됩니다.

하지만 또, 문제가 되는 것은 UCS-2방식의 문자열들이 모두 BOM을 달고 있지는 않다는 점입니다. 이 것 때문에 다른 바이트 순서를 사용하는 시스템에서 문제가 생길 수 있습니다.

  1. 0번 평면의 문자들만 인코딩 했기 때문에 모든 유니코드 문자를 표현할 수 없습니다.

UTF-32

기본 다국어 평면(BMP)만을 이용한 UCS-2와는 달리 UTF-32는 유니코드의 모든 문자를 표현하기 때문에 한 글자당 32비트를 사용하는 인코딩입니다.

표현 방식

UTF-32에서 앞에 2바이트는 [0x00 0x00]부터 [0x00 0x10]까지 몇 번째 평면인가를 표시합니다. 그리고 뒤에 2바이트는 UCS-2와 같이 해당 평면의 어느 문자인지를 나타냅니다.

[0x00 0x01](1번 평면) [0x00 0x10](해당 평면의 문자)

UTF-32의 장점

유니코드를 그대로 4바이트 자리에 가져다 놓았기 때문에 유니코드와 비교하기 쉽고, 한 글자에 고정 4바이트를 할당하기 때문에 문자열 처리가 간결해집니다.

UTF-32의 단점

  1. 한 글자에 고정적으로 4바이트를 할당하기 때문에 다른 인코딩 방식에 비해서 많은 용량을 차지하고 있습니다.

ex) 같은 문자라도 ASCII 코드와 비교해서 용량이 4배나 차이가 나게 됩니다.

  1. HTML5에서 사용 금지

→ HTML5.1 사양 4.2.5.5 챕터에는 아래와 같이 명시되있습니다.

이런 문제들 때문에 UTF-32은 거의 사용되지 않고 있습니다.

UTF-16

UTF-16은 너무 많은 용량을 사용하는 UTF-32 인코딩의 문제를 해결하기 위해 나온 가변 길이 인코딩 기법입니다.

UTF-16은 기본 다국어 평면에 속하는 문자들을 표현할 때는 UCS-2와 같지만, 2바이트를 넘어서는 문자는 4바이트를 표현하도록 하여 문제를 해결했습니다.

그래서 기존의 UCS-2 16비트 인코딩과 호환이 되면서도 16비트를 넘어서는 문자를 가변 길이 인코딩으로 표현이 가능하게 되었습니다.

문자 표현

2바이트 : 기본 다국어 평면(BMP)

4바이트 : 2바이트를 넘어선 모든 유니코드 문자

UTF-8

UTF-8은 가장 많이 사용되는 가변 길이 인코딩입니다. 문자에 따라서 1바이트 ~4바이트로 인코딩 될 수 있으며, UTF-16과 다르게 아스키 코드와 하위 호환성을 가집니다.

 

보통 유니코드가 널리 쓰이기 전에 형성된 문서나 프로그램이 아스키 코드를 기반으로 작성되었기 때문에 UTF-8은 이 부분에서 많은 장점을 가지게 되어서 널리 쓰이게 되었습니다.

 

 

'IT' 카테고리의 다른 글

프로젝트 시작시 해야할것들  (0) 2021.10.05
ASCII Code, Unicode, encode, decode (2편)  (0) 2021.10.01
맥 TouchEn nxKey 문제 해결  (2) 2021.04.19
Jira 도입 리뷰  (0) 2021.03.30
IT팀과 협업하기, 업무 발의  (0) 2021.03.30

댓글