프로그래밍 2016. 6. 4. 23:08

API 몇개를 만들던 중 문자열이 심심치 않게 깨지는(euc-kr -> utf-8)  그리고 기타 특수문자들의 전송에 있어서 json 디코딩이 안되는 이런 뭐 몇가지 문제를 겪다가 기본 인코딩 원리 및 정확한 처리 방법을  알 필요가 있다고 생각하며 정리해본다.  

결국 바이트?비트? 전송을 어떤 크기로 잘라서 읽어 들여 특정 맵핑(표준 정의)에 맞추어 본다고 정리 할 수 있을듯 하다.(나만의 정리)

크게 본다면 문자를 표현하는것은 아스키를 처음으로 시작된다. 0x00 ~ 0xff 까지 255개의 문자를 정의한다. 

여기서 중요하게 생각해볼 것은 한글과 그것의 인코딩이다. 위에서 말한 아스키는 한글을 표현하기에 부족하다. 보통 중국,한국,일어에 사용되기 위해서는 더 큰 범위의 처리 방법이 필요한 것이다.

그렇다면 한글은 어떻게 표현되는것인가? 크게 조합형과 완성형으로 나누며, N바이트 완성형/조합형 식으로 나누어 볼 수 있다. 조합형이란 한글의 초/중/종성(19,21,28)에 각 코드를 부여하고 조합(11172개)하여 표현하게  하는 것이다. 그에 반해 완성형은 지금 쓰고 있는 글자 처럼 완성된 글자에 코드를 부여하는 방식이다. 

2바이트 조합형/완성형을 알아보면 

조합형에서는 초/중/종성에 각 5bit를 할당하여 맵핑하고, 처음 1bit(msb)는 1로 마킹하여 한글임을 표시하였다. 

완성형은 각 음절을 코드와 1:1 맵핑시킨 것이다. ISO 2022 표준을 기준으로 하였으며, 이것은 0xA1A1 ~ 0xFEFE(8836개)를 사용하였다. 하지만 한자에 4888, 러시아 1598을 사용하여 한글에는 2350개 밖에 사용되지 않았다. 그래서 몇개의 문자를 표현할 수 없었다. 그러다가 MS가 추가 재정하여 나머지 8822자를 추가하였다. 통합형 한글 코드, 확장 완성형이라고 한다.

이제 유니코드ㄱㅏ 나올 때이다. 중어, 일어등을 표현하기 위해서는 EUR-JP, EUC-CN 뭐 등등의 인코딩이 쓰인다. 하지만 우리는 이것들을 모두 사용하는 문서들을 표현해야한다. 어떻게 모든 문자를 표현하게 할가? 기존의 한가지 글자에 대한 표현방식을 사용할 수 없어, 나온 것이 유니코드이다. 이 모든것을 모아서 만들어낸것이다.  한글 11172 문자가 모두 표현가능하다.

유니코드에서는 코드포인트라는 것을 사용한다. A의 유니코드값은 U+0041로 표현한다. 31bit문자 집합이며, 현재까지 21bit내에서 다 표현이 가능하다고 한다. 

한글은 u+1100 ~ u+11FF사이에 한글 자모, u+AC00 ~ u+D7AF 사이의 한글 소리 마디 영역에 표현되어 있다.

유니코드의 인코딩 방식(utf-8)을 알아보자. 

U+0000~U+007F

 7

그대로 인코딩

U+0080~U+07FF

11         

110xxxxx 10xxxxxx

U+0800~U+FFFF

16

1110xxxx 10xxxxxx 10xxxxxx

U+10000~U+1FFFFF    

21

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

문자를 2진수로 표현 후 xxx부분에 기존 비트값을 넣어준다. 

"한글" 을 코드 포인트로 보면 U+D55C U+AE00인데, 이를 UTF-8 인코딩하면, 0xED 0x95 0x9C 0xEA 0xB8 0x80이 된다.

그리고 한글의 범위는 AC00 ~ D7AF 이므로 한글은 3바이트 인코딩으로 다 가능하게 된다.




'프로그래밍' 카테고리의 다른 글

git 변경된 파일 무시하기.  (0) 2016.07.04
Java 메모리 관리(스택프레임)  (1) 2016.06.05
strategy pattern(전략 패턴)  (0) 2016.05.29
templete method 패턴  (0) 2016.05.29
git fetch from remote  (0) 2016.04.07
//