한글 풀어쓰기→모아쓰기를 통해 얻은 지식들

by BLUEnLIVE | 2010/09/24 09:30

아이폰은 단점이 없는 완벽하고도 지고지순한 폰이 아니다. 철학이 뚜렷하고, 이에 따른 장단점이 명확히 나뉘는 폰이다. 그런데, 그런 원인...



1. 유니코드의 한글자소는 초중종성 정보가 있는 것과 없는 것이 별도로 존재

유니코드에는 (당연히) 음절 단위의 글자 외에도 한글자소가 별도로 존재한다.
그런데, 이 자소에는 초중종성의 정보가 있는 자소와 없는 자소가 별도로 존재한다.

일단, 정보가 있는 자소U+1100 부터 시작된다.
현대어→고어 순으로 할당되어 있으며, 현대어에는 ㅄ같은 문자가 초성에 할당되어있지 않았다.

초중종성 정보가 포함된 한글자소: U+1100부터 시작됨. 아래 표시된 부분은 종성 'ㄱ'


초중종성 정보가 없는 자소U+3131 부터 시작된다.
여기는 자음에 초성과 종성이 혼합되어 있으며, 이 순서는 완성형 한글의 순서와 정확히 일치한다.



2. 두 종류의 자소(U+1100, U+3131)를 완성형으로 변환시 문제 발생 가능

VC6은 기본적으로 유니코드가 아닌 완성형 코드를 지원한다.
그리고, 시스템에서 이를 유니코드로 변환할 때는 U+3131로 변환한다.
즉, 아래와 같은 코드를 실행시켰을 때...

CFileFind finder;
BOOL bOk = finder.FindFile(_T("c:\\*.txt"));
while (bOk)
{
  bOk = finder.FindNextFile();
  if (finder.IsDots() || finder.IsDirectory()) continue;
  _trename(finder.GetFilePath(), _T("c:\\말도안돼.txt"));
}

c:\ㅁㅏㄹㄷㅗㅇㅏㄴㄷㅙ.txt가 존재하더라도 한글자소가 U+1100으로 저장되어 있다면 rename되지 않는다.
왜냐하면 _trename()의 내부에서는 이런 순서로 진행되기 때문이다.

API: U+1100 → finder.GetFilePath(): 완성형 변환_trename(API): U+3131 변환

따라서, 멀쩡히 있는 파일명을 API를 통해 읽은 뒤 다른 이름으로 바꾸는 작업이 불가능할 때도 있는 것이다.
물론, 해결책은 있고, 간단하다. 컴파일러를 유니코드 모드로 설정하면 된다.


3. 유니코드 한글은 조합형으로 구성되었음

한글을 조합하는 방법에 대해 이리저리 고민했는데, 알고보니 유니코드의 한글 코드는 조합형으로 구성되어있다.
보통 조합형 한글이라는 개념은 2바이트(16비트)를 1비트(무조건 1)+5비트(초성)+5비트(중성)+5비트(종성)으로 구성하는 방식을 의미한다.


하지만, 유니코드의 한글은 이런 비트를 조합하는 방식은 아니다. (그런 테이블을 할당받을 수도 없음)
U+AC00부터 초성 19자, 중성 21자, 종성 28자를 순서대로 배치하는 것이다.


예컨데, 이라는 글자의 코드는 U+AC00 + 7(ㅂ)*21*28 + 15(ㅞ)*28 + 9(ㄺ) = U+DBC1이다.
이러한 원리를 이용해서 간단한 식만으로 한글을 조합하거나, 자소를 분리해낼 수 있는 것이다.

유니코드의 각국어 할당표를 만드는 과정에서 여러나라들의 수많은 알력이 있었다.
유니코드의 한글구성표를 만드는데 노력하시고, 박터지게 싸우신 모든 분들께 감사드린다.


덧. VC++ 6.0도 유니코드를 기본으로 사용할 수 있음

메뉴에서 Project → Settings... 선택한 뒤, C/C++ 탭에서 Preprocessor definitions:를 찾는다.
여기서 _MBCS를 찾아 _UNICODE로 바꾼다.


다음으로, Link 탭에서 Output을 선택한 뒤 Entry-point symbol:wWinMainCRTStartup으로 지정한다.