UTF-8? 유니코드? 한글 표현 방식이 궁금하다...
문자셋과 인코딩
-
문자셋(Character Set)
문자 코드의 집합
-
인코딩(Encoding)
문자 표현 방법
유니코드 = 문자셋 UCS(Universal Character Set) + 인코딩(UTF-8,16,32)
유니코드도 완성형과 조합형 모두다 정보를 가지고 있다. 완성형 같은경우는 초성을z축, 중성을 x축, 종성을 y축으로 구성하여 간단한 산술연산을 통해 분리해 낼 수 있다.
텍스트에 대한 규칙 = 정규화 방식 = NFC,NFD,NFKD,NFKC 등이 있다.
NFC vs NFD
- NFC(Normalization Form Composition)
NFC는 모든 음절을 Canonical Decomposition(정준 분해) 후 Canonical Composition(정준 결합) 하는 방식이다. 즉, 각
을 각
이라는 하나의 문자로 저장하는 방식이다. 이 방식을 사용하면 NFD 방식보다 텍스트의 사이즈는 작아지게 된다. 하지만, 옛 한글 자모의 결합으로 이루어진 한글 음절 코드가 없으므로 이 음절은 Canonical Composition 하지 못하므로 자소가 분리된 체로 저장하게 된다. 이로 인해, 현대 한글과 옛 한글이 다른 방식으로 저장되므로 텍스트를 처리할 때 유의해야 한다.
NFC는 많은 GNU/Linux 시스템, Windows에서 주로 사용한다.
- NFD(Normalization Form DeComposition)
NFD는 모든 음절을 Canonical Decomposition(정준 분해)하여 한글 자모 코드를 이용하여 저장하는 방식이다. 즉, 각
을 ㄱ
+ ㅏ
+ ㄱ
로 저장하는 방식이다. 이 방식은 현대 한글과 옛 한글을 동일한 방식으로 저장한다는 장점이 있지만 NFC 방식과 비교하여 텍스트의 크기가 커진다는 문제가 있다.
NFD는 macOS 시스템에서 주로 사용한다.
- NFKC, NFKD NFKC와 NFKD는 또 다른 NFC, NFD 정규화 방식이다. 많은 사람들이 NFC와 NFD만 한글 유니코드를 처리하는데 쓰이고 NFKD/NFD, NFKC/NFC의 차이가 없다고 생각한다. 이는 한글 음절/자모 유니코드에서 호환분해 과정과 정준분해 과정이 동일하기 때문에 생기는 인식이다.
NFKC와 NFKD는 한글자모/한글음절 영역 이외의 한글 유니코드 영역을 처리할 때 유용하게 사용할 수 있다. 다음 표를 참고하면 각 유니코드 클자가 정규화 방식에 따라 어떻게 변하는 가를 확인할 수 있다.
NFC | NFD | NFKC | NFKD | 비고 | |
---|---|---|---|---|---|
각(AC01) | 각 (AC01) | 각 (1100 + 1161 + 11A8) | 각 (AC01) | 각 (1100 + 1161 + 11A8) | 한글음절 |
ㄱ (1100) | ᄀ (1100) | ᄀ (1100) | ᄀ (1100) | ᄀ (1100) | 한글자모 |
ㄱ (3131) | ㄱ (3131) | ㄱ (3131) | ᄀ (1100) | ᄀ (1100) | 호환자모 |
㈀ (3200) | ㈀ (3200) | ㈀ (3200) | (ㄱ) ( ‘(‘ + 1100 + ‘)’ ) | (ㄱ) ( ‘(‘ + 1100 + ‘)’ ) | 자모괄호기호 |
㈎ (320E) | ㈎ (320E) | ㈎ (320E) | (가) ( ‘(‘ + AC00 + ‘)’ ) | (가) ( ‘(‘ + 1100 + 1161 +,’)’ ) | 음절괄호기호 |
㈝㈝ (321D) | ㈝㈝ (321D) | ㈝㈝ (321D) | (오전) ( ‘(‘ + C624 + C804 + ‘)’ ) | (오전) ( ‘(‘ + 110B + 1169 + 110C + 1165 + 11ab + ‘)’ ) | 오전괄호기호 |
㉠ (3260) | ㉠ (3260) | ㉠ (3260) | ᄀ (1100) | ᄀ (1100) | 자모원기호 |
㉮ (326E) | ㉮ (326E) | ㉮ (326E) | 가 (AC00) | 가 (1100 + 1161) | 음절원기호 |
ᄀ (FFA1) | ᄀ (FFA1) | ᄀ (FFA1) | ᄀ(1100) | ᄀ (1100) | 자모반각기호 |
이처럼 NFKC/NFKD의 호환분해는 단순히 자모를 분리/결합할 뿐만 아니라 각종 한글 특수 기호 또한 정규화를 진행한다. 모든 기호를 오직 한글음절/한글자모로 변환하므로 한글 특수기호를 다룰 일이 있다면 유용하게 쓰일 수 있을 것이다.
조합형 vs 완성형
-
조합형 방식
한글의 편리함을 그대로 가지고 있는 방식입니다. 자음과 모음을 초성, 중성, 종성으로 구분하여 문자를 작성하는 방식을 이야기 합니다. 초성, 중성, 종성을 각기 따로 인식하고 그 것들을 하나의 바이트로 인식하고 조합되어, 총 3바이트의 문자로 인식합니다. -
완성형 방식
문자를 하나의 완성되어져 있는 글자로 인식하는 방식입니다. 한글이 “가”부터 만들어 질 수 있는 문자표를 토대로 문자를 인식합니다. 유니코드보다는 확장성이 떨어지는데 그 이유는 만약 “꽰” 이라는 글자가 완성형 문자표가 있지않다면□
식으로 표기가 됩니다.
조합형 UTF-8
UTF-8 : 유니코드를 위한 인코딩 방식.
서버 : 대부분의 서버들의 운영체제는 리눅스 계열입니다. 리눅스 계열의 대부분은 유니코드를 지원합니다.
웹서버(Apache,IIS,NginX) : UTF-8 채택
PHP,MySQL : UTF-8 채택
리눅스 + Apache = 둘다 조합형이기 때문에 한글 표현 문제 안생김. 윈도우 + Aapche = 윈도우는 완성형이기 때문에 경로에 한글이 있어서 문제가 발생.
완성형 EUC-KR, CP949
EUC-KR은 웹에서 자주 사용하는 완성형(쀏
처럼 없는 문자가 많아서 웹페이지에서 표시 안됨)
CP949는 MS에서 사용하는 완성형 (MS가 모든 한글을 완성형으로 만들어서 표시 가능)
표현 관계
완성형 중에서 EUC-KR의 경우에는 종종 빠져있는 문자가 있지만, 확장 완성형인 CP949의 경우에는 유니코드(UTF-8)에서 표현할 수 있는 모든 문자를 표현 가능합니다. 따라서 웹을 사용하지 않는 윈도우 환경이라면 크게 불편함이 없을 수 있습니다.
하지만, 웹에서의 관계는 위에처럼 표현가능한 것이 아니라, UTF-8이면 UTF-8, EUC-KR이면 EUC-KR끼리 밖에 제대로 표현을 못합니다. 이런 상황을 생각해보면 각종 웹 소스들을 사용할 때 인코딩 부분만 해결하면 될 것 같습니다.
그리고 cp949는 MS에서 마음대로 설정한 한글 표현방식 때문에 어순에 따라 Sorting하는데 문제가 발생합니다.
인코딩을 변환하도록 하는 함수도 있고, 서버 자체의 인코딩을 바꾸는 방법도 있습니다.
한글 인코딩 확인 목록
- 서버 OS 인코딩
- 웹 서버 인코딩
- PHP 인코딩
- 웹 소스 인코딩
- 데이터베이스 인코딩
- 또 다른 문제 : BOM(Byte Order Mark) =
바이트 스트림의 특정 부분에 삽입되는 3바이트 마크
Mac,iOS,리눅스에서 윈도우에서 보낸 데이터를 읽을때 문제가 발생함. 윈도우에서는 BOM을 명시적으로 사용하지만 다른곳에서는 사용하지 않기 때문에, 읽어올때 이상하게 읽어옴.
참고 자료
- https://studyforus.tistory.com/167 [Study For Us]
- https://meetup.toast.com/posts/35 [정성환 NHN엔터테인먼트 / P-Flat개발팀]