JDK 1.1, 1.2의 한글 관련 인코딩과 기타


[ 다음 글들 ] [ 이어서 글올리기(답하기) ] [ 자바 묻고 답하기 ]

글쓴이 :김덕태 1998년 4월 22일 16:13:34

Jungshik Shin wrote:
> 염려하신대로 JDK 1.1.5에서 확인해 본 결과 상당히 문제가 많은 것을 알
> 수 있었습니다. Sun이 Cp949(UHC/통합 완성형)을 무엇을 보고 구현했는지
> 모르겠지만(
> 에 가면 Cp949 <-> UCS-2 변환 표가 있습니다), UCS-2에서 Cp949로 바꾸는
> 과정에서 KS C 5601-1987에서 정의하지 않은 글자에 대한 변환이 엉망입니다.
> 반대로 Cp949에서 UCS-2(혹은 UTF8)로 바꾸는 과정 역시 틀렸습니다.
>
> 다음을 컴파일하신 다음에 'Cp949'를 명령행 인자로 주고 UHC를 지원하는
> 터미널에서 한번 결과를 보십시오. 혹은, Unix의 hexdump
> ("hexdump -e '"%07.7_ax " 16/1 "%2_u " "\n"'"나
> "hexdump -e '"%07.7_ax " 16/1 "%02X " "\n"'") 같은 것으로 확인해
> 보십시오. JDK 1.2 beta3에서 한번 시험해 보시고 결과를 알려 주시면
> 고맙겠습니다. 만일, JDK 1.2beta3에서도 그 버그가 그대로 남아 있다면 JDK
> 1.1.5에서 발견한 두어 가지 다른 문제(한국어 locale에서 날짜 표시 형식의
> 문제 등. 아래에 적습니다)와 함께 모아서 수정을 요구해야겠습니다.
>
> --------Cut-----------Here----------------------------
> import java.io.*;
> import java.text.*;
> import java.util.*;
>
> public class KoreanTest
> {
> public static void main(String[] args)
> {
> String encoding = "KSC5601";
>
> //EUC_KR should be used in place of KSC5601,
> //but it's not yet supported as of JDK 1.1.5
>
> if ( args.length > 0 )
> encoding = args[0];
> try
> {
> PrintWriter out = new PrintWriter(
> new OutputStreamWriter(System.out, encoding) );
>
> for ( int i=0; i < 11172 ; i++) {
> char c = (char) ( i + 0xac00) ;
> out.print(c);
> if ( i%28 == 27 ) { out.print('\n');}
> }
> out.close();
> }
> catch (IOException e)
> { System.out.println("Error" + e); }
> }
> }
> -----------------Cut----------Here----------------



인코딩 지원의 의미
====================


자바에서 인코딩을 지원한다는 것의 의미는 자바가 사용하는
내부코드인 유니코드 2.0의 코드값과 이들 인코딩에서의
코드값을 변환해주는 클래스가 제공된다는 것과
인코딩 이름을 지정해줄 수 있는 모든 곳에서 이들 인코딩 이름을
사용할 수 있다는 것입니다.



인코딩 이름 (썬사에서 공표하는 이름, 표준 이름, alias 이름)
==========================================================


이들 인코딩 이름은 썬사에서 공표하는 이름과 이에 대응하는 alias
이름들이 있으며 서로 동일합니다. 썬사에서 공표하는 이름은 코드 변환
클래스 이름을 만드는 데 사용되므로, 식별자로 사용될 수 있기 위해서
EUC-KR 대신 EUC_KR이란 이름을 사용합니다.


또한, 인코딩 이름은 대소문자 구분이 없음에도 불구하고 썬사에서
공표하는 인코딩 이름은 소문자 형태를 이해하지 못합니다. 즉, euc_kr은
인식하지 못함.


EUC_KR에 대해서는 euc-kr이란 표준 이름이 alias로 되어있으므로 EUC-KR도
사용가능하며, 더 바람직한 이름일 것입니다.



JDK 1.2beta3에서 지원되는 한글 관련 인코딩
==========================================


JDK 1.2beta3가 지원하는 한글 관련 인코딩은 문서화된 것과 그렇지 않은
것 모두 포함하여 다음과 같습니다.



// 유니코드 문자 외부 인코딩


"UTF8", // UTF-8
"Unicode", // Unicode 2 bytes external encoding with byte order mark
"UnicodeBig", // Unicode 2 bytes external big endian encoding with byte order mark
"UnicodeLittle", // Unicode 2 bytes external little endian encoding with byte order mark
"UnicodeBigUnmarked", // Unicode 2 bytes external big endian encoding with no byte order mark
"UnicodeLittleUnmarked", // Unicode 2 bytes external little endian encoding with no byte order mark


// 아스키 인코딩


"Default",
"ASCII", /* alias: */ "us-ascii",


// 한국 문자 인코딩


"EUC_KR", // Korean, KS C 5601-1987, EUC Encoding
/* alias: */ "euc-kr", "euckr", "KSC5601", "ksc_5601",
/* alias: */ "ksc5601_1987", "ks_c_5601-1987", "ksc5601-1987",
"Cp949", "Cp949C", // Korean, PC
"Cp970", // Korean, AIX


"Johab", // KS C 5601-1992, Microsoft Unified Hangul Encoding
// (US-ASCII + KS C 5601-1987 + 11172 Modern Hangul Syllables ?)
/* alias: */ "ms949", "windows-949", "ksc5601-1992", "ksc5601_1992",


"ISO2022KR", // Korean, ISO 2022 KR


"Cp933", // Korean Mixed with 1880 UDC, superset of 5029



JDK 1.1.5에서 지원되는 한글 관련 인코딩
==========================================


// 유니코드 문자 외부 인코딩


"UTF8",
"Unicode",
"UnicodeBig",
"UnicodeLittle",
"UnicodeBigUnmarked",
"UnicodeLittleUnmarked",


// 아스키 인코딩


"Default",


// 한국 문자 인코딩


"KSC5601", // Korean, KS C 5601-1987, EUC Encoding
/* alias: */ "ksc_5601", "ks_c_5601-1987"
/* alias: */
"Cp949", "Cp949C", // Korean, PC
"Cp970", // Korean, AIX


"ISO2022KR", // Korean, ISO 2022 KR


"Cp933", // Korean Mixed with 1880 UDC, superset of 5029



Cp949에 대해
==============


자바에서의 Cp949는 마이크로소프트 통합 완성형 코드를 의미하지
않으며, 대신 JDK 1.2의 ms949라는 인코딩 이름이 이에 해당합니다.
ms949는 Johab이라는 인코딩 이름의 alias이므로 서로 동일합니다.
즉, 통합 완성형 코드를 조합형 코드라는 의미가 강한 Johab이란
이름을 사용하였으므로 무언가 잘못되었다는 생각입니다.


KSC5601-1992에 대해서는 잘 모르겠으나, KSC5601-1992가 정의하는
문자세트을 모두 표현할 수 있는 인코딩이기때문에 (맞나?) 대표하는
인코딩으로 Johab이란 이름을 사용한 것으로 추측합니다.


썬사에서 949 코드를 이와 같이 2가지로 나눈 것은
마이크로소프트사가 Cp949의 의미를 변경시켰기 때문이 아닌가
추측하고 있습니다.
윈도우즈 3.1에서 Cp949가 사용되고 있다면, 그런 경우에도
통합 완성형 코드의 의미를 갖는가요?


결론적으로, ms949라는 인코딩 이름을 사용하여, 통합 완성형 코드의
모든 문서, 자료를 모든 자바 1.2 플랫폼에서 처리할 수 있다는 것입니다.
또한, 눈에띄는 버그도 없었습니다.


하지만, 사용자가 모두 자바 1.2 환경 및 윈도우즈 환경만을 사용하는 것은
아니므로, 그 인코딩을 사용하는 경우에는 이러한 제한점을 고려해야 할
것입니다.


JDK 1.1에서와는 달리 JDK 1.2는 폰트 처리 방식이 바뀐 것 같습니다.
즉, 윈도우즈용 JDK 1.2에서는 유니코드 2.0의 모든 현대한글이
그래픽 기능을 사용하여 출력하지 못합니다.


이러한 문제는 이 ms949 인코딩을 사용하여 유니코드 2.0 코드로부터
949 코드값으로 변환하여, 이 코드값이 한글 폰트의 인덱스로 사용하도록
jdk1.2beta3/lib/font.properties.ko 화일을 수정하면 됩니다.


http://calab.kaist.ac.kr/~dtkim/java/example/bug/font.properties.ko.jdk12.windows.bugpatch
은 이와같이 수정된 화일입니다.


신정식님이 올리신 다음 프로그램중 "KSC5601" 을 "ms949"로 바꾼 후
실행시켜보면, 윈도우즈의 도스창에서는 모든 현대 한글이 가나다라 순서로
바르게 출력이 됩니다. 하지만, 유닉스의 hanterm, vi등 여러
프로그램에서 기대되지 않는 코드값이 끼치는 영향은 다양하더군요.
엉뚱한 문자로 보인다던가, 정상적인 문자도 영향을 받아 깨져서
보인다던가... 또한, 코드값을 세밀히 관찰하지 않고서는 언뜻보아서
euc-kr 문서인지, ms949인지, 훼손된 문서인지 분간하기도 어렵습니다.
표준화되지 못한 another encoding이 끼치는 악영향이라고 볼 수 있겠죠.



> String encoding = "KSC5601";
===> String encoding = "ms949";




코드 값 테이블과 다국어 출력
============================


자바의 다국어 출력에 관심이 있으시거나, 여러가지 인코딩의 코드값에
대해서 쉽게 알고싶으시면
http://calab.kaist.ac.kr/~dtkim/java/example/i18n/CodeTable.java
을 가져가서 사용해보시면 도움이 될 것입니다.


또한, http://calab.kaist.ac.kr/~dtkim/java/example/i18n/CodeTable.html
을 JDK 1.1 지원 브라우저로 방문하시면 애플릿으로 실행시킬 수 있습니다.


다음과 같은 4가지 목적을 위해 만든 것입니다.


* Program Type: Applet/Application
*
* Purposes:
* 1. Display diverse characters in diverse encodings graphically
* with their code values.
* 2. Show the corresponding code values between any 2 character encodings.
* 3. Find code conversion or character display bugs of Java versions.
* 4. Provide a simple Unicode input method (in the future).


한글뿐만 아니라 다양한 인코딩에 대해서 알고자하는 경우, 문자를
출력해서 코드값과 함께 보아야만 인코딩의 코드값이 무엇을 의미하는 지
이해가 갈 것입니다. 윈도우즈 1.1에서는 익스프로러 4.0의 도움말/제품
업데이트 기능을 통해서 통합 유럽 폰트, 중국 폰트, 일본 폰트를 모두
설치할 수 있으며, (익스플로러 없이 설치할 수 있는 방법을 아시는 분?)
유닉스용으로는 GNU emacs 다국어 폰트를 설치할 수 있습니다.
유니코드로부터 이들 폰트의 인덱스로 매핑해주는 자바용 폰트 매핑 화일을
http://camars.kaist.ac.kr/~dtkim/java/index 에서 가져다가
jdk1.x\lib\font.properites.ko 화일을 대체하면 됩니다.


이때, font.properites.ko 화일을 일반 사용자가 수정해야 한다는 문제점을
갖고 있습니다.
JDK 1.2에서는 시스템에 설치되어 있는 폰트 목록을 알아낼 수 있으므로,
이러한 작업이 필요없을 것 같습니다.
또한, 이때문에 JDK 1.2 베타판들의 초기 기동 시간이 오래걸리는 것으로
알려져 있습니다.
하지만, 이러한 방법으로 한글 폰트도 알아내고 이용할 수 있는 지는
아직 조사해보지 못했습니다.


한가지 궁금한 것은 Win32 API중에서 TextOutA와 TextOutW라는
함수를 사용하여 문자를 출력할 수 있다고 하는 데,
이때, TextOutW에 유니코드 2.0 코드값을 인자로 넘겨서 출력할 수 있나요?
그런경우, True Type 폰트내의 유니코드 맵 테이블을 이용해서 출력을
하게 되나요?
그렇다면, Latin-1 문자를 이 함수를 사용하여 유니코드로 출력하는 경우,
font association에 영향을 받지 않고 한글이 아닌 Latin-1 문자로
출력이 되나요?
이런 질문을 하는 이유는, 자바의 폰트 매핑 화일을 아무리 바꾸고
cyberbit 폰트를 설치하고, MS의 다국어 폰트를 설치하고, 그 폰트내의
유니코드 맵 테이블을 이용해보려고 애써도 한글 윈도우즈에서는
모두 실패했기때문입니다.
또한, 유니코드 맵 테이블을 이용하지 못하면, 폰트내의 모든 문자를
자바에서 제대로 이용할 수가 없습니다.
하지만, 영문 윈도우즈에서는 이런 문제가 생기지 않는 것 같더군요.
이부분은 어느분이든지 아시는대로 꼭 답해주셨으면 좋겠습니다.



>
> Cp949 문제 이외에 다음과 같은 문제가 JDK 1.1.5에 있습니다.
....
>
> 2. 현재 EUC-KR, ISO-2022-KR, UHC/Cp949, IBM의 AIX에서 쓰는 것(아마,
> EUC-KR 변형) 등의 인코딩을 지원하는데(물론, UTF8은 디폴트로
> 지원하지요), "조합 인코딩"도 -실제로 얼마나 쓸 지는 모르지만-
> 지원해 주어야 할 것으로 봅니다.


조합 인코딩 지원에 대해서는 용도를 잘 모르겠군요.
통합 완성형은 코드값이 지저분하기는 하지만, 조사해보니 특수 기호를 피해나가는 등
문제의 소지를 최소화하려는 노력이 엿보이더군요.


>
> 3. 이것은 한국어 locale에만 해당하는 얘기는 아닌데, 도대체 locale과
> 시간대를 연관시키는 것은 누구의 발상인지 모르겠군요. 한국어 locale을
> 쓴다고 해도 미국 동부 시간대를 쓸 수도 있고, 중부 유럽 시간대를 쓸 수도
> 있을텐데, 한국어 locale을 고르면 현재 시스템의 시간대 설정을 무시하고
> 무조건 한국 표준시로 시간을 표시하다니 어처구니가 없윱求.


로캘과 시간대가 전혀 다른 개념임을 자바소프트 및 연합 회사의 엔지니어들이
몰랐을리가 없을 것입니다.
자바가 시스템에 설정된 시간대를 알아내는 데 초기부터 문제가 많았으며,
또한, 시간대 이름이 충돌하는 경우도 많은 것 같더군요.
(KST라는 이름이 다른 나라에도 사용되나요?)
아마도, 이런 문제점을 피해나가기 위한 임시 방편이 아니었나라고
추측하고 있습니다.


>
> 4. 이것도 일반적인 문제인데 locale 설정을 해도 그에 대응하는 인코딩을
> 손쉽게 설정할 방법(인코딩은 따로 설정해야 함)이 없는 것도 문제인 것
> 같습니다. ko_KR 같으면 locale 설정시 EUC_KR, ISO-2022-KR, Cp949/UHC,
> JOHAB, UTF8 등의 인코딩도 지정할 수 있으면 더 좋을 것 같다는 생각입니다.


시스템 locale 설정에서의 인코딩 지정은 시스템이 지원하는 것으로만 한정되는
것 같습니다.
아시다시피 자바는 대단히 많은 인코딩을 지정하고 있으며, 시스템의 기능 추가는
일반적으로 쉬운 것이 아니므로, 자바만이 이해하는 인코딩 환경 변수를
추가시킨다면 될 것 같습니다.
아직은 그런 환경 변수가 없는 것으로 알고 있으며,
현재로서는 자바 애플리케이션의 경우에 한하여,
-Dfile.encoding=ms949 등의 명령행 인자를 사용하는 방법이 있습니다.


제가 드린 질문에 대하여 누군가 잘 설명해주시면 좋겠습니다.


--
Deogtae Kim (김덕태)
CA Lab. CS Dept. KAIST
http://calab.kaist.ac.kr/~dtkim/java





다음 글들:



이어서 글올리기(답하기)

이름:
E-Mail:
제목:
내용:
관련 URL(선택):
URL 제목(선택):
관련 이미지 URL:


[ 다음 글들 ] [ 이어서 글올리기(답하기) ] [ 자바 묻고 답하기 ]