티스토리 뷰

Encoding

[Encoding]유니코드(Unicode)

heyhyo 2018. 6. 25. 18:26

유니코드는 전 세계의 모든 문자들을 컴퓨터에서 표현하고 다룰 수 있도록 설계된 산업 표준이다. 이 표준은 유니코드 협회(Unicode Consortium)가 제정한다. 이 표준에는 ISO 10646 문자 집합, 문자 인코딩, 문자 정보 데이터베이스, 문자들을 다루기 위한 알고리즘 등을 포함하고 있다.


유니코드가 등장하기 이전의 문자 코드들은 한정된 범위의 문자를 표현하여 만약에 다른 문자 집합(Character Set)을 사용하는 컴퓨터에서는 표시될 수가 없었다. 따라서 세계의 모든 컴퓨터 환경에서 문자 인코딩 방식이 호환되지 않아 불편함을 느껴 유니코드를 개발하게 되었다. 유니코드가 만들어 진 후부터는 컴퓨터 소프트웨어가 같은 문자인코딩으로 해석될 수 있었기 때문에 국제적으로 널리 퍼질 수 있게 되었으며, 현재는 다양한 최신기술과 운영 체제에서도 지원하고 있다.


* ISO 10646 문자 집합이란 ISO(International Organization for Standardization, 국제 표준화 기구)에서 지정한 표준 중 하나로 UCS(Universal Multiple-Octet Coded Character Set)라는 이름을 가진 표준이다. 이는 멀티 바이트로 한 문자를 나타내는 문자 집합과 그 부호를 나타낸다.




Unicode vs UTF-8



우리가 프로그래밍을 하다보면 UTF-8이라는 것을 쉽게 찾아볼 수 있다. HTML파일 헤드태그에 아래 태그는 거의 필수적이다.


<meta charset="utf-8">


나는 이 태그를 명시함으로써 자세하게는 모르지만 세계의 수많은 문자들을 표현할 수 있게 해준다는 것 정도만 알고 스쳐 지나갔던 이슈이기도 하다. 이왕 쓰는거 확실하게 알고 가면 좋지 않을까?






위 그림을 보면 01001000이라는 데이터를 UTF-8방식으로 'H'라는 한 문자로 디코딩하는 모습을 볼 수 있다. UTF-8은 유니코드에 명시된 코드값을 통해 디코딩을 실행한다.


쉽게 설명하자면 UTF-8은 유니코드를 이용하는 인코딩 방식중에 하나이다.


결국 유니코드는 세계의 대부분의 문자들을 일대일로 맵핑시켜놓은 코드라고 할 수 있고, 그것을 컴퓨터에서 사용할 때 유니코드를 어떠한 방식으로 처리하여 이용할 것인가를 정해주는 것, 즉 인코딩하는 여러가지 방법중에 하나가 UTF-8이라고 할 수 있다.


정리하자면 유니코드(Unicode)는 코드와 문자를 매핑 시켜놓은 집합이라고 이해하면 되겠고, UTF-8은 그 코드표를 이용한 인코딩 방식으로 이해할 수 있다.




인코딩 방식



유니코드의 문자열 집합을 이용하여 실제 컴퓨터에서 사용하기 쉽도록 여러가지 인코딩 방식들이 있다. UTF-8, UTF-16, UTF-32를 기준으로 설명해 보겠다.


UTF-8(8-bit Unicode Transformation Format)


문자열 집합과 인코딩 형태를 8비트 단위로 한다는 의미를 가지고 있다. 유니코드 한 문자를 나타내기 위해서 1바이트에서 4바이트까지를 사용한다. 그래서 이를 가변 길이 인코딩 방식이라고 한다. ASCII문자들은 7비트로 표현이 가능하여 1바이트로 하나의 문자를 표현이 가능한데 아스키를 주로 사용하는 시스템에서 모든 문자를 4바이트로 사용한다면 이것은 지나친 저장소의 낭비가 될 수 있다. 그래서 아스키코드로 표현가능한 것들은 1바이트로 표현하고 그것이 안된다면 2바이트 이상을 사용하는 방식이다.


여기서 의문을 가질 수 있다. 어떻게 가변길이로 문자를 표현할 것인가? 그것은 첫번째 바이트가 시작되는 비트가 무엇이냐에 따라서 뒤의 몇바이트까지 읽어낼 것인가를 결정하게 된다.


0xxxxxxx 첫번째 바이트가 0으로 시작한다면 0 이외의 7비트를 ASCII로 인식한다.

110xxxxx 10xxxxxx 두번째 바이트까지 읽어서 하나의 문자로 표현

1110xxxx 10xxxxxx 10xxxxxx 세번째 바이트까지 읽어서 하나의 문자로 표현

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 네번째 바이트까지 읽어서 하나의 문자로 표현


여기서 UTF-8의 강점은 ASCII방식과 완벽하게 호환된다는 것이다. 첫자리를 0으로 채우고 나머지 7비트를 통하여 ASCII와 일대일로 대응하도록 표현이 가능하다. 2바이트 이상일 때는 첫 바이트의 최상위비트부터 0인 비트까지의 1인 비트의 수가 바이트의 수를 나타낸다. 위에서 설명했듯이 110 이면 1인 비트가 2개이므로 2바이트까지를 하나의 문자로 보는 것이다. 그리고 첫 바이트다음에 나오는 바이트는 10으로 시작하는 원칙을 따른다. 이것은 한 문자를 표현하는 바이트들이 다른 문자의 것으로 혼동되는 것을 막기위한 방법이다.


최근에 표준으로 가장 많이 사용되고 있는 인코딩 방식이라고 할 수 있다.



UTF-16(16-bit Unicode Transformation Format)


UTF-16은 16비트(2바이트)단위로 인코딩 된다. 2바이트 단위로 인코딩하여 고정 길이 인코딩 방식이다. 기본 다국어 평면의 문자들은 16비트가 그대로 문자로 인코딩 될 수 있으며, 그 이외의 문자는 특별히 정해진 방식으로 32비트로 인코딩 된다. 따라서 2바이트 또는 4바이트로 문자가 인코딩된다.


여기서 질문이 나올 수 있다. '왜 고정길이면서 16비트와 32비트로 크기가 변경되는가?' 이렇게 반문한다면, 데이터의 크기에 초점을 맞추지 않았으면 한다. 왜냐하면 고정길이라는 것은 특정한 데이터가 어떠한 기준이되는 크기의 블록에 들어가서 그 단위로 처리된다는 것이다. UTF-16같은 경우는 2바이트, 4바이트의 크기의 블록에 유니코드를 적재하여 인코딩하는 방식이라는 것이다. 따라서 데이터가 만약 그 블록보다 작다면 빈 공간이 존재하게 된다. 가변길이 라는 것은 데이터의 크기에 알맞게 그 블록의 크기가 조정되는 것으로 이해하면 쉬울 것이다.


UTF-8과 비교했을 때 ASCII와의 호환성이 떨어지는 문제가 있지만, UTF-16은 한글을 2바이트로 표현이 가능하다. 따라서 UTF-8이 한글을 3바이트로 표현하는 것으로 보아, 한글로 된 문서들을 표현하기에는 UTF-8이 데이터의 크기에서 이점을 가져갈 수 있는 인코딩 방식이다. 하지만 대부분의 컴퓨터 환경들은 영어로 구축되어 있기에 영어를 1바이트로 표현할 수 있는 UTF-8이 거의 표준처럼 사용되고 있는 추세이다.


Java언어에서는 이 인코딩 방식을 표준으로 사용하고 있다. 그래서 char형 변수는 하나에 2바이트로 잡혀서 사용하는 것이다.



UTF-32(32-bit Unicode Transformation Format)


UTF-32는 32비트(4바이트)단위로 인코딩 된다. 모든 문자들을 4바이트 단위로 인코딩하기 때문에 고정 길이 인코딩 방식이라고도 불린다.


네트워크에서는 거의 사용되지 않는다고 봐도 무방하다. 왜나하면 모든 문자가 4바이트로 고정되기 때문에 낭비되는 비트가 많아질 수 있기 때문이다. 모든 유니코드의 문자를 표현하려면 21비트를 사용하는데 32비트중 11비트는 의미없이 남아버리는 것이다.


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


최근의 컴퓨터가 용량이 충분해져 이 방식도 내부적으로는 사용되고 있다. Python3.3 이상의 버전부터는 내부적으로 UTF-32를 통해 처리하기도 한다.




왜 등장하였는가?



생각해보면 구지 이렇게 인코딩 방식을 다양하게 할 필요가 있을까? 하는 반문을 할 수 있게 된다. '그냥 제일 좋은거 하나만 있으면 되는거 아니야?' 하는 생각이 들기 마련이다. 하지만 이것에도 이유가 있다.


처음에 UTF-8이 등장하였다. 이 인코딩 방식으로 사전적인 모든 문자들은 표시할 수 있었다. 하지만 사람들은 사전적인 문자 이외에 이모티콘과 더 많은 한자를 표현하고 싶어졌다.


그래서 좀 더 확장하여 2바이트 단위의 인코딩 방식인 UTF-16이 등장하였다. UTF-16에서는 한자와 이모티콘 마저 표시할 수 있게 되었다. 하지만 지구촌 시대에서 다양한 문자들을 표기하기에는 2바이트의 그릇도 작았다.


더 확장하여 4바이트 단위의 인코딩 방식인 UTF-32가 등장하였다. 이 인코딩 방식은 비로소 사람들이 원하는 모든 문자를 표현할 수 있게 되었다. 아주 넉넉한 그릇이었다. 하지만 너무 커져버린 그릇은 저장소의 낭비로 이루어졌다.


그래서 데이터의 크기가 중요한 곳에는 UTF-8이 사용되기에 용이해지고, 다양한 문자를 포괄하여 표현하기에는 UTF-16과 UTF-32가 더 적합했다. 결국에 자신이 필요한 용도에 맞춰서 사용할 수 있도록 다양한 인코딩 방식이 공존하게 된 것이다.




결론



이외에도 수많은 인코딩 방식이 있지만 처리하는 데이터의 종류에 따라서 사용하는 시스템에 따라서 적절한 인코딩 방식을 사용해야한다. 상황에 따라서 UTF-8과 UTF-16의 인코딩 결과의 크기가 달라질 수도 있고, 데이터 처리를 간소화하는 UTF-32방식도 사용될 수 있다는 것이다. 결국 이런 인코딩 방식의 다양화는 다양한 컴퓨터 환경에서의 호환성과 다양한 언어를 표시하고자 하는 사람들의 욕망에 의해서 나타났다는 것을 알게 되었다.




참고



https://namu.wiki/w/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C

https://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C

http://norux.me/31

'Encoding' 카테고리의 다른 글

[Encoding]Base64  (2) 2018.06.25
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함