Know/Java

캐릭터셋 관련

Marine™ 2006. 1. 5. 15:06
반응형
원문 : http://javaservice.net/~java/bbs/read.cgi?m=devtip&b=servlet&c=r_p&n=1038800530&p=1&s=t#1038800530

제목 : [Comment] 다국어 인코딩 문제의 위치 및 까발리기
글쓴이: EB(goEB) 2002/12/01 22:42:10 조회수:386 줄수:289

======== 2002.12.03 23:12 공지 ========
이 글의 KSC5601-1992는 잘 못되었으므로 걸러서 읽어주시기 바랍니다.
이 글과 관련된 "2부"에서 설명합니다.
=======================================



제목 : [Comment] 다국어 인코딩 문제의 위치

많은 분들이 다국어 때문에 헤메이고 있습니다.
이에 대해 저의 짧은 지식이지만 공유할 까 해서 코멘트를 달아봤습니다...


글의 영양가는 뒷부분에 있습니다.
시간 없으신 분들 장문인 만큼 뒷부분을 읽어주십시오. 다만 문자셋의 기본은 --;;


이 글에선 DB는 부분은 범위밖이기 때문에 다루지 않을 것입니다.
사실 대부분의 문제는 DB외의 곳에서 발생할 것입니다.


저는, 엔코딩에서 제일 중요한 것을 아래와 같이 분류하였습니다.
1. 각 문자셋의 종류와 이해
2. 소스 파일의 엔코딩 형태
3. 컴파일된 파일의 엔코딩 형태
4. 컴파일된 파일을 사용하는 엔코딩 형태
5. UTF-8의 필요성 인식.
6. WebBrowser의 이상한 행동(?)

"new String(str.getBytes("8859_1"), "EUC_KR");"
와 같은 문제는 별개입니다. (문자셋의 종류와 이해가 우선이지요)


<
1번에서 주의해야 할 것은. Unicode와 Unicode(UTF-8)을 동일시 여겨셔는 안된다는 것입니다.
Unicode는 코드페이지 1200이며, Unicode(UTF-8)은 65001 입니다.
그 크기 또한 다릅니다. (하늘과 땅차이 -_-)

- Unicode와 Unicode(UTF-8)을 간단 정리
Unicode는 모든 문자를 2Byte로 표시한다. - ISO-2022형태의 다국어와 차이점.
(영문이고 다국어고 필요없다. 어떤 언어든 65536가지를 표현 가능하다.
이 뜻은 2Byte가 어떤 형태로 구성되는지를 알 수 있게 하는 말.)

UTF-8은 기존 ASCII 1xx까지 유지하며 다국어는 2, 3Byte로 표시한다.
(즉, 영문은 1Byte처리 - 아래에서 다시 설명하기 때문에 매우중요)
고로, UTF-8은 프로그래밍 언어에 사용하여도 손색이 없다.

☆다국어 - 여기서 필자 맘대로 재정의한 뜻으로 기존 2Byte이상을 필요하던 언어.
(영어등도 포함해서 말한다고 딴지 걸지 말란 뜻에서;;;)
>


<
2번을 이해하지 못하였을 경우에는 이러한 문제들이 발생합니다.

가. 만약 소스가 JSP일 경우 파일을 Include할 때 A는 정상인데 B는 깨지거나
하는 문제 발생. (혹은 그 반대)
※주의! <%@ page contentType="text/html;charset=xxx"%> 와는 별개이므로 소용 없습니다.
나. *.java를 컴파일 한뒤 다국어 사용시 깨어져 나온다. --;;
(static이나 비교문등에 미리 입력해 놓은 다국어...)
물론 Runtime시 복구할 수 있는 경우도 겠지만 그렇게 하는 사람 있다면 따돌림 당한다는.... --;;

해결법 :
가. 소스파일을 만들어 저장할 시에 자신이 작성한 소스의 문자셋을 확인한뒤
그 와 동일하게 저장하도록 하고, 프로젝트에 관련된 모든 파일을 동일한 문자셋으로 작업해야 한다는...
<%@ page contentType="text/html;charset=xxx"%>의 xxx에 자신이 작성한 문자셋을 동일하게 입력.
만약 기존에 미리 만들어둔 소스가 있을 경우라면 밑에서 다시 언급하겠습니다.
나. 소사파일을 만들어 저장할 시에 자신이 작성한 소스의 문자셋을 확인한뒤
그 에 따라 컴파일 할 수 있도록 한다.
>


<
3, 4번의 경우는 현재로써는 가정이다. (혹은 사실 - 물론 내 자신은 아직 접한적은 없다.)

컴파일된 파일이 JVM에 의하여 로딩되는 과정과 Runtime의 과정에서 엔코딩이 서로다른 형태의
Class를 불러 들였다면? 그렇다면 이중 entrypoint가 있는 클래스가 디코딩의 기준이
되는 것일까? 그렇다면 entrypoint외의 타 클래스에서 사용된 다국어는 모두 깨어질 것이다.
아니라면 클래스간 호출시 JVM은 그 에 따른 처리를 해야한다. (느려진다.)

물론 현재의 JVM은 일반적으로 모든 소스를 Unicode 혹은 UTF-8로 불러들일 테지만 아닐 경우는 어찌 해야 할 까?
(컴파일된 파일의 원본의 형태가 뭐건 Unicode 혹은 UTF-8로 변형)

이렇게 3, 4번을 넘기자 --;;
>


<
5는 2번의 경우만으로도 UTF-8의 필요성을 느끼지 않을 수 없겠습니다.

번거롭게 경우에 따라 소스를 다시 원하는 형태로 엔코딩하여 만들어야 한다는 것은
Tool과의 노가다를 감행해야한다는 것인데 말이죠.
그러므로 할 일 많(-_-)은 프로그래머로써는 UTF-8을 사용해야 한다는...

또한, UTF-8의 정렬속도 쥑입니다. --b (Unicode와의 비교를 제외한다면.)
한글이 모두 순차배열되어 있기 때문입니다. :)
그에 비해KSC5601(KSC5601-1992)는 정렬속도는 떨어진다는... (공포의 8822자)
>


<
Application에서 프로그램 소스등(*.JSP, *.JAVA, *.TXT)의 엔코드 타입을 자동으로 인식!?!
결론은 자동 인식 가능한 문자셋이 있기도 없기도 입니다.
일반적으로 2Byte로 된 문자셋은 인식이 불가능 하지만 Unicode는 가능 합니다.
첫 시작을 16진수로 FF FE로 시작하는 문서는 Unicode를 알리는 문서입니다.
또한 Unicode(UTF-8)은 서명있는 Unicode(UTF-8) 문서일 경우는 대부분 가능합니다.
없는 경우는 가능한 툴이 있기도 하고요. (말이 자동이기 거의 강제 --)
만약 서명이 있는 경우라면 EF BB BF로 시작합니다.
이에 따라 각종 Tool에서 자동으로 읽을 수 있는 것입니다.
>



소스의 문자셋을 변경사용하기...

일반적으로 프로젝트의 모든 소스는 엔코딩 형식이 동일해야 하겠죠?
만일 기존 소스가 있는데 다르다면 현 프로젝트와 맞추어야 할 텐데...
쉽게 구할 수 있는 툴은 UltraEdit가 정도가 되겠네요 저는 v9.10을 가지고 있고
File -> Conversions에 있습니다. 이 곳에서 원하는 형태로 가능하겠습니다.

-단, 한글들의 문자셋변환 툴은 아직 보질 못했음. 혹시 보신분 손 ^^/
한글에서 하위변환은 완벽히 안되므로 이를 염두해야함.



JSP에서 <%@ page contentType="text/html;charset=xxx"%>와
META TAG의 contentType="text/html;charset=xxx"

이둘을 사실상 모두 사용하는 경우는 웃지 못할 일입니다.
(실로 대단한 이슈입니다.)

이곳 게시물중
----------------------------------------------------------------------------------
==게시물 1========================================================================
euc-kr 이나 ksc5601 을 사용할 경우 브라우저의 한글은 잘 나온다.

대신 확장한글을 표시할 수 없어서 샾 , 햏 , 잌 같은 글자는 ? 로 깨어져 나온다.

소스보기를 해도 완전히 깨진다.
...
...
중략
...
서버쪽 한글처리는 MS949 로 정하고, 브라우저의 한글처리는 ksc5601, euc-kr 등으로
한다. 즉 서버쪽은 @page 의 contentType 속성을 charset=MS949 로 태그 내의
태그에서 Content-type 의 값을 charset=ksc5601 로 주면 브라우저쪽의
한글처리를 마무리지을 수 있다.
==게시물 2========================================================================
NOTE: '잌'과 같은 확장한글의 경우는 추가적인 테스트가 필요합니다.
추정컨데,
1) MS949(Cp949)를 DB(Oracle,DB2,..)가 지원하는가?
2) JVM file.encoding MS949->Cp949 에서 정상적인 동작을 하는가?
3) default.client.encoding/client.encoding.override MS949->Cp949 에서 정상적인
동작을 하는가?
4) 위 팁문서처럼 META tag에서 KSC5601을 반드시 써 주어야 하는가?
==게시물 3========================================================================
Windows에서의 JVM의 한글디폴트 인코딩 캐릭터셋 문자열은 "EUC_KR" 입니다.
Linux에선 "KSC5601"이라 나오는 군요.

그러나 "EUC_KR", "KSC5601", "EUC-KR"은 모두 동일합니다.
==================================================================================
----------------------------------------------------------------------------------
이런 내용이 있었습니다.

MS949는 엄밀히 "KSC5601-1987" 입니다. 또한 "KSC5601-1992" 입니다.
KSC5601이들의 차이점은 1992는 1987를 모두 포함하고 문자의 위치까지 호환이 되며
1987에 추가된 문자 8822(공포의)개가 있다는 것 뿐입니다.
(현재 MS OS에서는 단순한 폰트차이로 봐도 무방)
그러므로 일반적으로 KSC5601라고 통합하여 사용하는 것입니다.
(엄밀히 MS949는 META TAG에서 windows-949 혹은 ks_c_5601-1987 에 해당합니다.)

그러니 위에 언급된 게시물에 있는 MS949관련 사건들은 무효-_-가 아닐까요?

무슨 의미인고 하니 EUC-KR(Extended Unix Code-Korean)에서는 잌이 깨지지만 KSC5601은 깨지지 않습니다.
쓩, 잌, 퓩, 끁, 덁을 비교해보면 EUC-KR은 쓩만을 표현할 뿐 입니다.
KSC5601-1992는 확장을 표함합니다. (물론 UTF-8과는 비교할 것이 못되지만...)
하지만 EUC-KR은 확장을 포함하지 않습니다.
(위의 게시물 3은 2000/05/28일자로 오래되었기에
그 시절 KSC5601 = EUC-KR 라고 한 표현한 것은 그다지 문제 삼을필요는 없는듯 --;;
다만 저 게시물을 보고 아직 맞다고 생각하시는 분들을 위하여 언급하였음.)


어쨌든 어떠한 환경이던 WebBrowser간엔 어떤 문자셋이건 쌍통합니다.
(이점이 중요합니다. 왜 깨어져야할 확장 글씨가 정상 표시되는지를 이제 설명합니다.
-MS Win XP에서 IE 6.0과 Nescape Navigator 7.0을 테스트 해봄. Linux, Unix에서 안해봄)

제가 위에서 언급한 확장글씨가 왜 이곳 게시판이 EUC-KR임에도 불구하고 깨지지 않고 정상으로 보일까요?


WebBrowser는(어쩌면 OS레벨) HTML 소스의 문자셋이 뭐건 Unicode (단, UTF-8 문자셋은 제외)로 변환시킵니다.
그리고 화면에 출력합니다. 이 때 필드(INPUT TAG, TEXTAREA TAG등)에 입력한 값 역시
당연 Unicode(UTF-8인지는 정확히 확인하지 않았음. 하지만 UTF-8문자셋은 그대로 UTF-8) 데이터 입니다.
(눈으로는 구분 못하죠.)
그래서 입력할 당시에는 모든 문자를 입력할 수가 있는 것입니다.
허나 값을 서버로 보내면 HTTP Header (혹은 META TAG)에 정의된 문자셋으로 컨버팅 합니다.
(Server로 전송되는 TCP/IP 데이터를 보면 증명 가능)
이 때 컨버팅 불가능한 문자는 &# + Unicode값 으로 변경됩니다. 그렇게 서버로 날라가는 것입니다.
(이 값만으로도 알 수 있겠지만 EUC-KR은 KSC5601에 비해 확장한글이 부족하단것을 알 수 있습니다.)

만약 서버에 날라간 엔코딩 타입이 KSC5601이였지만 깨지는 문자가 있었다면, 그 깨지는 문자는
&# + Unicode 형태로 계속 보존되게 되는 것입니다. DB에 역시 그렇게 입력됩니다.
그렇다고 한다면 눈치빠른 분들은 벌써 한가지 이상의 문제를 지적하실 것입니다.

첫째. &# + Unicode 로 표현된 문자는 특수처리를 하지 않는다면 영원히 그렇게 되어 있다는 것을...
(많은 문자셋을 보시면 알겠지만 ACSII는 유지되기 때문입니다.)
고로, WebBrowser 이외의 곳에서는 문제가 --;;
-이 때문에 DB에서 검색할 경우에 문제가 있다.

둘째. 기존 &# + Unicode를 추후 Unicode, UTF-8등에 마이그레이션 할 때 따로 작업 해야 할 것입니다.
(제가 아직 자동변경해주는 툴은 못 봤습니다. --;;
뭐 그리 어려운건 아니지만 양이 크면 큰일인 것 만은 확실합니다.)

셋째. DB의 필드의 길이가 개발자가 원했던 길이를 벗어날 수도 있는 문제.
&# + Unicode는 최대 7자의 길이를 가집니다. (MAX :
반응형