[유니코드] 한글 인코딩 개념과 발생하는 문제점 정리
[유니코드] 한글 인코딩 개념과 발생하는 문제점 정리

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 완성형

img

  • 조합형 방식
    한글의 편리함을 그대로 가지고 있는 방식입니다. 자음과 모음을 초성, 중성, 종성으로 구분하여 문자를 작성하는 방식을 이야기 합니다. 초성, 중성, 종성을 각기 따로 인식하고 그 것들을 하나의 바이트로 인식하고 조합되어, 총 3바이트의 문자로 인식합니다.

  • 완성형 방식
    문자를 하나의 완성되어져 있는 글자로 인식하는 방식입니다. 한글이 “가”부터 만들어 질 수 있는 문자표를 토대로 문자를 인식합니다. 유니코드보다는 확장성이 떨어지는데 그 이유는 만약 “꽰” 이라는 글자가 완성형 문자표가 있지않다면 식으로 표기가 됩니다.

조합형 UTF-8

UTF-8 : 유니코드를 위한 인코딩 방식.

서버 : 대부분의 서버들의 운영체제는 리눅스 계열입니다. 리눅스 계열의 대부분은 유니코드를 지원합니다.

웹서버(Apache,IIS,NginX) : UTF-8 채택

PHP,MySQL : UTF-8 채택

리눅스 + Apache = 둘다 조합형이기 때문에 한글 표현 문제 안생김. 윈도우 + Aapche = 윈도우는 완성형이기 때문에 경로에 한글이 있어서 문제가 발생.

완성형 EUC-KR, CP949

EUC-KR은 웹에서 자주 사용하는 완성형(처럼 없는 문자가 많아서 웹페이지에서 표시 안됨)

CP949는 MS에서 사용하는 완성형 (MS가 모든 한글을 완성형으로 만들어서 표시 가능)

표현 관계

img

완성형 중에서 EUC-KR의 경우에는 종종 빠져있는 문자가 있지만, 확장 완성형인 CP949의 경우에는 유니코드(UTF-8)에서 표현할 수 있는 모든 문자를 표현 가능합니다. 따라서 웹을 사용하지 않는 윈도우 환경이라면 크게 불편함이 없을 수 있습니다.

하지만, 웹에서의 관계는 위에처럼 표현가능한 것이 아니라, UTF-8이면 UTF-8, EUC-KR이면 EUC-KR끼리 밖에 제대로 표현을 못합니다. 이런 상황을 생각해보면 각종 웹 소스들을 사용할 때 인코딩 부분만 해결하면 될 것 같습니다.

그리고 cp949는 MS에서 마음대로 설정한 한글 표현방식 때문에 어순에 따라 Sorting하는데 문제가 발생합니다.

인코딩을 변환하도록 하는 함수도 있고, 서버 자체의 인코딩을 바꾸는 방법도 있습니다.

한글 인코딩 확인 목록

  1. 서버 OS 인코딩
  2. 웹 서버 인코딩
  3. PHP 인코딩
  4. 웹 소스 인코딩
  5. 데이터베이스 인코딩
  • 또 다른 문제 : 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개발팀]