Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 12개 있습니다.)
.NET Framework: 326. 유니코드와 한글 - 유니코드와 닷넷을 이용한 한글 처리
; https://www.sysnet.pe.kr/2/0/1294

.NET Framework: 411. 유니코드의 "compatibility character"가 뭘까요?
; https://www.sysnet.pe.kr/2/0/1607

.NET Framework: 429. C# - 유니코드 한글 문자열을 ks_c_5601-1987로 변환하는 방법
; https://www.sysnet.pe.kr/2/0/1657

개발 환경 구성: 230. 유니코드의 Surrogate Pair, Supplementary Characters가 뭘까요?
; https://www.sysnet.pe.kr/2/0/1710

.NET Framework: 450. 영문 윈도우에서 C# 콘솔 프로그램의 유니코드 출력 방법
; https://www.sysnet.pe.kr/2/0/1712

.NET Framework: 794. C# - 같은 모양, 다른 값의 한글 자음을 비교하는 호환 분해
; https://www.sysnet.pe.kr/2/0/11710

개발 환경 구성: 407. 유니코드와 한글 - "Hangul Compatibility Jamo"
; https://www.sysnet.pe.kr/2/0/11724

Windows: 176. Raymond Chen이 한글날에 밝히는 윈도우의 한글 자모 분리 현상
; https://www.sysnet.pe.kr/2/0/12369

닷넷: 2307. C# - 윈도우에서 한글(및 유니코드)을 포함한 콘솔 프로그램을 컴파일 및 실행하는 방법
; https://www.sysnet.pe.kr/2/0/13794

개발 환경 구성: 731. 유니코드 - 출력 예시 및 폰트 찾기
; https://www.sysnet.pe.kr/2/0/13798

개발 환경 구성: 732. 모바일 웹 브라우저에서 유니코드 문자가 표시되지 않는 경우
; https://www.sysnet.pe.kr/2/0/13799

닷넷: 2310. .NET의 Rune 타입과 emoji 표현
; https://www.sysnet.pe.kr/2/0/13813




Raymond Chen이 한글날에 밝히는 윈도우의 한글 자모 분리 현상

우리에게는 "레이몬드 첸의 윈도우 개발 282 스토리"라는 책의 저자로 알려진 Raymond Chen이 이번에는 한글날에 맞춰 윈도우의 한글 자모 분리 현상에 대한 뒷이야기를 남겼습니다.

A consequence of being the first to adopt a standard is that you may end up being the only one to adopt it: The sad story of Korean jamo
; https://devblogs.microsoft.com/oldnewthing/20201009-00/?p=104351

우선 이해를 돕기 위해, 한글 문자를 맥과 윈도우에서 표현하는 방법을 알아보겠습니다.

윈도우의 경우, 가령 '각'이라는 문자를 '각'을 나타내는 0xAC01 2바이트로 나타냅니다.

[윈도우]
 - U+AC01 '각'

반면 맥의 경우에는 '각'이라는 문자를 각각의 초성, 중성, 종성을 따로 분리해 표현을 하지만, 화면에 보여줄 때는 '각'이라고 합쳐서 보여줍니다.

[맥]
 - U+1100 'ᄀ'
 - U+1161 'ᅡ'
 - U+11A8 'ᆨ'

즉, 윈도우의 경우에는 '각'을 표현하기 위해 2바이트가 필요한 반면, 맥의 경우에는 6바이트가 필요(현실적으로는 UTF-8 인코딩을 하므로 윈도우는 3바이트, 맥은 9바이트)합니다. 이것을 유니코드의 정규화 관점에서 보면, 윈도우는 "NFC"를 따르고 맥의 경우에는 "NFD"를 따른다고 설명합니다.

문제는, ICU(Internationl Components for Unicode)도, iOS도, Android도 모두 U+1100, U+1161, U+11A8을 하나의 글자로 합쳐서 보여주는데, 왜 윈도우만 그것을 곧이곧대로 'ᄀ ᅡᆨ'으로 보여주냐는 것입니다. Raymond Chend은 이에 대해 '가장 먼저 표준을 도입하는 선발 주자로써 겪게 되는 아픔'의 한 사례라고 합니다. 실제로, 윈도우는 당시 한국의 산업 표준인 "KS X 1026"에 따라 NFC 방식이 되었다고 합니다.

Korean standard KS X 1026
; http://unicode.org/L2/L2008/08225-n3422.pdf

위의 문서에 "4. KS x 1026-1"을 보면,

  1. Modern Hangul Syllable Blocks - Only code positions of Wanseong (Precomposed) Hangul Syllable block (UAC00 ~ D7A3)
  2. Old Hangul Syllable Blocks - Only code positions of Johab Hangul Jamo block (U11xx)
  3. Two or more code positions of simple letters cannot be concatenated to represent a complex letter.
  4. A Wanseong Syllable block (UAC00 ~ UD7A3) and Johab Hangul letter(s) (U11xx) cannot be concatenated to represent another Hangul Syllable block. Ÿ Implementation algorithms for separating, searching, sorting and normalizing Hangul text syllables.

(3번과 4번은 차치하고) 현대 한글은 "Hangul Syllables"에 해당하는 AC00 ~ D7A3 범위의 완성형 코드를 쓰되, 옛한글(Old Hangul Syllable Blocks)은 "Hangul Jamo"에 해당하는 1100 ~ 11FF 범위의 조합형 코드로 쓴다고 언급이 됩니다. 즉, 일반적인 한글에 해당하는 '각'은 'ᄀ', 'ᅡ', 'ᆨ'로 따로 보관하지 않고 '각(U+AC01)'이라는 2바이트 완성형 한글을 쓰고, 옛 한글 - 예를 들어 '가ᇫ'이라는 글자는 맥에서처럼 "U+1100 U+1161 U+11EB"의 조합형으로 나타내라는 것입니다.

위키백과 문서를 보면 이에 대해 더 쉬운 설명을 포함하고 있는데요,

KS X 1026-1
; https://ko.wikipedia.org/wiki/KS_X_1026-1

위의 문서에 "금지된 조합"을 보면,

1) 조합형 한글 낱자 여러 개를 이용하여 겹낱자를 표현하지 않는다.
    예: ᄖ U+1116 (O),  U+1102 U+1107 (X)

2) 현대 한글 완성자는 반드시 한글 글자 마디(Hangul Syllables, U+AC00~U+D7AF) 영역의 문자로 표현해야 하며, 조합형 한글 낱자로 표현하지 않는다.
    예: 한 U+D55C (O), ᄒ ᅡ ᆫ U+1112 U+1161 U+11AB (X)

3) 옛한글 완성자를 표현할 때 한글 글자 마디 영역의 문자와 조합형 한글 낱자를 섞지 않는다.
    예: 가ᇫ U+1100 U+1161 U+11EB (O), 가ㅿ U+AC00 U+11EB (X)

두 번째 항목이 실제로 많이 볼 수 있는 맥의 표현으로 분명히 "KS X 1026-1" 표준 문서에는 그렇게 하지 말라고 명시하고 있습니다.

이런 설명과 함께, Raymond Chen은 윈도우가 잘못된 이유를 물을 것이 아니라, 오히려 다른 운영체제들의 잘못된 이유를 물어야 한다고 합니다. 즉, 아무도 지키지 않는 표준을 구현한 운영체제들 속에 단 하나의 표준을 구현한 운영체제가 잘못된 것처럼 보이게 된 것입니다.

어쨌든 결국, 이런 상황으로 인해 윈도우가 따르는 공식적인 표준인 NFC 방식과, 그 외의 운영체제들이 따르는 사실상의 표준인 NFD 방식으로 나뉘게 되었다고.




저 스스로가 개발자이다 보니, 사실 개인적인 관점에서 보면 만약 한글을 구현해야 했다면 NFD 방식을 따랐을 것입니다. 왜냐하면... ^^; 그것이 더 구현이 쉽습니다. 완성형 한글 속에서 옛 한글은 조합형으로 표현해야 하는 "KS X 1026-1" 표준보다는 무조건 조합형으로 구현하는 NFD 방식이 확실히 구현상 쉽다는 이점이 있습니다.

그나저나, 여기서 글을 맺으면 좀 아쉽고 Raymond Chen의 글에 달린 덧글에 보면 반박글이 재미있습니다. 즉, 맥과 같은 운영체제들이 구현한 방식이 표준이 아니라고 하는데 사실 유니코드 표준에 NFD 방식의 구현이 "UAX #29" 문서로 명확하게 나와 있다는 것입니다.

Unicode® Standard Annex #29
; http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries

(혹시... 저 현란한 문서 좀 정리해 주실 분 계실까요? ^^)

하지만 이에 대해서는 개인적으로 의문인 것이, 해당 문서의 초판 작성자가 "Authors Mark Davis (mark.davis@us.ibm.com)"으로 나오는데, 과연 저 문서를 작성할 때 한글 관련 부분에 대해 한국 측의 의견을 얼마나 잘 반영했느냐입니다. 혹시 이에 대한 이력을 아시는 한글 관련 전문가가 계시다면 덧글 부탁드리겠습니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 10/21/2020]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2020-10-14 04시44분
'샾' 등 한글 표현 문제 해결을 위한 공공 정보시스템 한글 처리 가이드라인
; http://m.korea.kr/expertWeb/resources/files/data/document_file/2010/공공%20정보시스템%20한글%20처리%20가이드라인.pdf

"
유니코드에서 한글 표현의 경우 KS X 1026-1으로 표준화되어 있고, 기술표준원 산하 문자코드위원회에서 이를 권고하고 있다
"
정성태
2021-10-20 08시46분
정성태
2022-09-29 04시17분
제 글로 인해 이런 논쟁이 발생했군요. (아마도!)

맥의 한글 파일명 분리에 대한 오해
; https://www.clien.net/service/board/park/17595712

심지어, "'가장 먼저 표준을 도입하는 선발 주자로써 겪게 되는 아픔'의 한 사례"라고 제가 의역한 문장까지 그대로 자신의 문장인 것처럼 사용하는 덧글도 보이고.
정성태

... 136  137  138  139  140  141  142  143  144  145  146  147  148  [149]  150  ...
NoWriterDateCnt.TitleFile(s)
1329정성태8/21/201222894오류 유형: 161. Azure - Storage 삭제가 안되는 경우 [1]
1328정성태8/20/201233294개발 환경 구성: 163. IIS 7 - "MIME Types" 설정 아이콘이 없는 경우
1327정성태8/19/201238039Windows: 58. Windows 8 정식 버전을 설치해 보고... [14]
1326정성태8/19/201224348오류 유형: 160. Visual Studio 2010 Team Explorer 설치 오류
1325정성태8/15/201224358개발 환경 구성: 162. 닷넷 개발자가 컴파일해 본 리눅스
1324정성태8/15/201226391.NET Framework: 332. 함수형 언어의 코드가 그렇게 빠를까? [4]파일 다운로드1
1323정성태8/4/201228161.NET Framework: 331. C# - 클래스 안에 구조체를 포함하는 경우 발생하는 dynamic 키워드의 부작용 [2]
1322정성태8/3/201227821개발 환경 구성: 161. Ubuntu 리눅스의 Hyper-V 지원 (마우스, 네트워크)
1321정성태7/31/201227098개발 환경 구성: 160. Azure - Virtual Machine의 VHD 파일 다운로드 [2]
1320정성태7/30/201229081Math: 10. C# - (타)원 영역의 마우스 클릭 판단파일 다운로드1
1319정성태7/26/201227620개발 환경 구성: 159. Azure - 네트워크 포트 여는 방법 [1]
1317정성태7/24/201226467오류 유형: 159. SpeechRecognitionEngine.SetInputToDefaultAudioDevice 호출 시 System.InvalidOperationException 예외 발생
1316정성태7/18/201284595개발 환경 구성: 158. .NET 응용 프로그램에서 Oracle XE 11g 사용
1315정성태7/17/201229389개발 환경 구성: 157. Azure - Virtual Machine 구성 [2]
1314정성태7/16/201224407개발 환경 구성: 156. Azure - 2개 이상의 서비스 계정을 가지고 있을 때 프로젝트를 배포하는 방법
1313정성태7/16/201236581오류 유형: 158. Hyper-V 설치 후 VM 시작이 안되는 경우
1312정성태7/15/201236453Math: 9. 황금비율 증명
1311정성태7/15/201229157Math: 8. C# - 피보나치 수열의 사각형과 황금 나선(Golden spiral) 그리기파일 다운로드1
1310정성태7/13/201232601Math: 7. C# - 펜타그램(Pentagram) 그리기파일 다운로드1
1309정성태7/13/201230671개발 환경 구성: 155. 윈도우 운영체제에서 기본적으로 사용할 수 있는 압축 해제 방법
1308정성태7/3/201226049.NET Framework: 330. IEnumerator는 언제나 읽기 전용일까?파일 다운로드1
1307정성태6/30/201228294개발 환경 구성: 154. Sysnet, Azure를 만나다. [5]
1306정성태6/29/201228879제니퍼 .NET: 22. 눈으로 확인하는 connectionManagement의 maxconnection 설정값 [4]
1305정성태6/28/201227056오류 유형: 157. IIS 6 - WCF svc 호출 시 404 Not Found 발생
1304정성태6/27/201227843개발 환경 구성: 153. sysnet 첨부 파일을 Azure Storage에 마이그레이션 [3]파일 다운로드1
1303정성태6/26/201227367개발 환경 구성: 152. sysnet DB를 SQL Azure 데이터베이스로 마이그레이션
... 136  137  138  139  140  141  142  143  144  145  146  147  148  [149]  150  ...