유니코드, 문자 세트, 인코딩의 개념, 자바의 인코딩 개념.


[ Follow Ups ] [ Post Followup ] [ 자바 묻고 답하기 ]

Posted by 김덕태 on July 05, 1997 at 10:21:40:

In Reply to: 유니코드와 UTF-8, 그리고 자바... posted by 김덕태 on July 02, 1997 at 10:01:40:

Jungshik Shin wrote:


> 이 부분은 조금 오해의 소지가 있는 듯 합니다. 워낙 이 부분의 용어가
> RFC나 표준 문서마다 제각각이어서 혼동을 초래할 수 밖에 없기B 합니다.
> 이를 정리하기 위한 노력의 일부인 RFC 2130에 비추어 볼 때 위의 단락은
> 좀더 조심스럽게 용어를 사용해서 쓰였으면 좋지 않을까 생각합니다.
>
> RFC 2130의 정의에 의하면 KS C 5601, KS C 5636(US-ASCII), Unicode 등은
> 문자셋(Coded Character Set=CCS)입니다. 이 문자셋(CCS)을 구체적으로
> 표현하기 위해 octet에 대응시키는 인코딩 방법(Character Encoding
> Scheme=CES)이 EUC-KR, ISO-2022(-KR), UTF-8(UTF-FSS), UTF-7,UTF-1 등이
> 있겠지요. 앞의 2개는 KS C 5601과 KS C 5636(US-ASCII)라는 2개의
> 문자셋(CCS)을 인코딩하는 방법(CES)이고 뒤의 세 개는
> Unicode(ISO-10646에서 BMP)라는 문자셋(CCS)을 인코딩하는
> 방법(CES)이겠지요.
>
> 따라서, "KS C 5601을 대체하는 인코딩으로 UTF-8을 쓴다"는 표현은 서로
> 개념적으로 다른 차원의 두 가지를 -KS C 5601은 CCS이고 UTF-8은 CES이므로
> - 같은 차원에 놓은 것으로 보입니다. 마찬가지로 'Unicode와 UTF-8을 같은
> 위치에 놓고 비교하여 어느 한 쪽이 다른 쪽보다 어떤 용도에 보다
> 적합하므로 더 우월하다 '고 하는 것도 혼동의 소지가 있습니다. UTF-8은
> 독립적인 문자셋(CCS)이 아니라 Unicode의 여러 가지 인코딩 방법(CES) 중
> 하나에(위에 적으신대로 'File System Safe'한 특성을 지녔기에
> UTF-FSS라고도 불리며 파일 저장 등에 적합한 CES로 알고
> 있습니다) 불과하니까요. 위의 글에서 Unicode란 단어를 Unicode란 CCS의
> '가장 자연스러운 인코딩' 방법의 의미로 사용하신 듯 합니다. 즉, "Unicode를
> network byte order에 따라 두 개의 octet의 나열로 표현한 인코딩
> 방법(CES)"의 의미로 사용하신 것으로 짐작합니다. 역시, KS C 5601도
> 사람들이 흔히 쓰듯이 KS C 5601과 KS C 5636(US-ASCII)란 2 개의 CCS를
> 전자는 G1에 후자는 G0에 두고 G0은 GL에 G1은 GR에 고정시킨 (ISO-2022 등에
> 대해 전혀 모르는 이라도 쉽게 생각할 수 있는 '자연스러운') 인코딩
> 방법의 의미로 쓰셨으리라 봅니다. 하지만, 이것은 이미 위의 괄호 안에서
> 지적하신 바처럼 EUC-KR로 정확히 부르는 것이 이런 종류의 논의를 할 때에는
> 혼동의 여지가 없으리라고 봅니다.


이런 복잡한 문제에 끌려(?) 들어가고 싶지는 않았지만 짚고 넘어가야 되는
문제로 생각되어 말씀하신 RFC 2130을 뒤져보았습니다.
관련 링크가 잘못되었더군요.
참고문헌 [1]에 가보니 관련 내용을 볼 수가 있었습니다.


======= RFC 2130 ========
RFC 2130은 인터넷 환경에 적합하고 호환성에 문제를 덜 일으키는 octect
(8 bit를 의미, `바이트'의 의미보다 더 엄밀함)를 기준으로 해서 문자
세트 및 인코딩과 관련된 사항을 다음과 같이 3 부분으로 나누어 놓았고,
각종 인터넷 표준을 정의하는 데 있어서 사용되는 용어, keyword등의
의미의 엄밀성과 일치성, 호환성을 기하기 위한 것이 목적일 것이며, 모든
프로그램과 자료가 인터넷만을 목적으로 하지 않는 이상, 이 분류에 맞지
않는 의미의 용어가 나름대로의 가치를 가지고 이와 구분되어 사용될 수
있는 것이라 생각됩니다.


1. A Coded Character Set (CCS) is a mapping from a set of abstract
characters to a set of integers. Examples of coded character sets
are ISO 10646 [ISO-10646], US-ASCII [ASCII], and ISO-8859 series
[ISO-8859].


여기서 정의하는 Coded Character Set의 의미는 각 추상적인 문자에
대하여 정수값을 할당하는 것이고, 정수라는 개념은 몇 비트로 표현한다는
것까지 정의하는 것은 아니므로, 인코딩과는 아무런 관련이 없는 추상적인
개념으로 볼 수가 있습니다.


2. A Character Encoding Scheme (CES) is a mapping from a Coded Character
Set or several coded character sets to a set of octets. Examples of
Character Encoding Schemes are ISO 2022 [ISO-2022] and UTF-8 [UTF-8].
A given CES is typically associated with a single CCS; for example,
UTF-8 applies only to ISO 10646.


말씀하신 대로 EUC-KR은 2개의 CCS (KS C 5601과 KS C 5636)의
CES입니다. 또한, UTF-8은 ISO 10646 CCS의 CES입니다.
KS C 5601을 각 정수 코드 값에 대하여 2 바이트 값으로 매핑한다고
가정한다면 CES로도 볼 수 있겠으나, 그와 같이 사용되는 경우가 거의
없으므로 (아스키문자도 섞어서 쓰므로), KS C 5601이라고만 한다면
CES를 의미하는 것이라고 볼 수 있을 것입니다.
또한, EUC-KR이 해당하는 KS C 5601과 KS C 5636의 합집합을
의미하는 CCS로도 볼 수도 있겠으나, 해당 CCS를 의미하는
용어가 이미 있으므로 EUC-KR이라고만 할 때는 CES를 의미하는 것이
적당할 것입니다. 하지만, 이는 해당 용어 및 keyword가 사용되는
context에 의해 결정되어야 할 것입니다.


참고문헌 [1]을 보면,
``Also, in MIME, the Coded Character Set and Character Encoding
Scheme are specified by the Charset parameter to
the Content-Type header field, and Transfer Encoding Syntax is
specified by the Content-Transfer-Encoding header field.''


즉, MIME에서는 charset 값은 CCS와 CES 둘다 의미하는 keyword이어야
하므로, EUC-KR이 사용된 경우에는 그 의미가 ``CCS는 KS C 5601과
KS C 5636의 합집합을 지정한 것이고, CES는 EUC-KR 인코딩이
나타내듯이 (NULL, 0) ~ (DEL, 127)은 해당 1 바이트로 매핑시키고,
(first_ksc5601_char, 0x2121) ~ (last_ksc5601_char, 0x7d7e)은
그 코드값을 x라 하면, x + 0x8080을 network byte order로 2 바이트로
매핑시키는 것을 의미한다.''라고 해당 표준 문서에 명기할 것을 추천하는
의도로 파악됩니다.


우리나라에서 현재 논란이 되고 있는 ISO-2022-KR의 경우도
MIME charset으로 지정된다면 마찬가지로 ``CCS는 KS C 5601 및 KS C
5636의 합집합을 지정한 것이고, CES는 ISO-2022-KR이 나타내는 CES를
지정한 것이다.''를 의미하는 것으로 정의해야 겠지요.


그러나, 유니코드 2.0이 의미하는 가장 일반적인 의미는 ISO 10646 BMP
및 plane 1 ~ plane 16의 문자를 16 비트 환경으로 인코딩하는 scheme
이라는 의미가 강하므로, RFC 2130의 정의를 따른다면 CCS로도 CES로도
보기 어렵다고 보고 있습니다.


3. Transfer Encoding Syntax
is frequently necessary to transform encoded text into a format
which is transmissible by specific protocols. The Transfer Encoding
Syntax (TES) is a transformation applied to character data encoded
using a CCS and possibly a CES to allow it to be transmitted.
Examples of Transfer Encoding Syntaxes are Base64 Encoding [Base64],
gzip encoding, and so forth.


TES는 CCS 및 CES와는 다소 독립적이며 특정 프로토콜이 이해하고
처리할 뿐 일반 사용자에게는 드러나지 않는 인코딩을 의미하는 것으로
CES와 구분되는 것 같습니다.
하지만, `possibly a CES'라고 되어 있는 점이 좀 비논리적인 것으로
보이는 군요.
CCS와 CES 둘다 정의되어 있지 않으면, 엄밀하게 octect stream
(간단하게 말하면, 바이트 열)으로 변환할 수 없고, 그렇다면, Base64
나 gzip 인코딩 또한 불가능하기 때문입니다.



==== 유니코드 2.0의 정의 =========
참고문헌 [2]의 페이지 1-1을 인용하면,
``The Unicode Standard is a fixed-width, uniform encoding scheme for
written characters and text.
... 중략 ...
The Unicode Standard is modeled on the ASCII character set, but uses a
16-bit encoding to support full multilingual text.''


즉, 유니코드 2.0은 16 비트 인코딩이 가장 정확한 의미라는 것입니다.
16 비트가 나타내는 코드 값으로 추상적인 문자와의 매핑을 정의하는
것으로 볼 수 있다면 CCS라고도 볼 수 있겠으나, 문제는 surrogate
area의 두개의 유니코드 값으로 하나의 추상적인 문자를 나타낸다는
것입니다. 이 surrogate area의 값은 ISO-10646의 plane 1 ~ 16부분에
해당하는 문자 (ISO-10646의 부분집합)로 매핑되게 됩니다. 따라서, 그
코드값을 정수로 표현하게 되면 0 ~ 65535의 범위를 넘어가게 됩니다.
이런 이유로, ISO 10646 BMP와 유니코드를 동일시할 수가 없습니다.


CES로도 볼 수 없는 이유는, 16 비트 인코딩이므로, 유니코드 코드 값의
상위 바이트와 하위 바이트가 어떤 순서로 저장 및 전송될지를
정의하지 않고, 각 시스템에 적합한 순서를 사용할 수 있게 한 것입니다.
그래서, 고정된 octect stream으로 만들어 낼 수 없으므로, 8 bit
인코딩이 될 수 없고 따라서 CES의 정의에 부합하지 못합니다.
참고문헌 [2]의 페이지 3-1을 보면, 바이트 순서에 대한 대한
어느 정도의 언급이 있지만, 완전한 것이라고 보기 어렵습니다.
따라서, 유니코드 + network byte order (big endian)이라고 말한다면
ISO-10646의 부분집합 CCS와의 매핑을 정의하는 CES라고 할 수 있습니다.


Unicode 라는 용어를 ISO-10646의 그 부분집합 CCS를 의미하는 것으로도
쓰일 수가 있겠지만, 이는 Unicode라는 용어가 함축하는 의미의 일부에
지나지 않는 것이므로, Unicode가 그와 같은 CCS를 나타내는 것으로
고정시킬 수도 없습니다. 혼란을 막기 위해서는 뭔가 다른 용어를
만들어 사용하여 해당 CCS를 의미하는 것으로 사용하는 것이 적당할
것으로 생각될 뿐입니다.


또한, 8 비트 인코딩 방법이 16 비트 인코딩 방법보다 더 구체적이라고
보지는 않으며, 단지 가정하는 환경이 다른 것이므로, 문자 자료가 16
비트 환경과 8 비트 환경을 넘나들 때, 문제가 발생할 소지를 안고 있는
것으로 파악하고 있습니다.
이는 7 비트 환경을 가정하는 ISO-2022-KR이 8 비트 환경을 가정하는
EUC-KR보다 더 구체적이라고 말하지는 않는 이유와 같습니다.
물론, 인코딩 방법이 가정하는 비트 수가 적을 수록 호환성에 문제가
적지만 내부적으로 처리하는 자료의 형식으로는 불편해지는 것으로
보아도 좋을 것입니다.


따라서, 유니코드와 UTF-8은 둘다 인코딩이므로, 프로그래밍 하는
사람의 입장에서는 적절한 인코딩을 사용하여 상황에 맞게 선택하여
사용하는 문제일 것입니다.
유니코드 인코딩을 사용할 경우에는, 바이트 순서가 문제가 되지 않는
경우에는 의미 있는 인코딩 방법이기 때문입니다.
(즉, 같은 바이트 순서를 가정하는 환경사이의 자료 저장, 교환 및
바이트 순서를 알아낼 수 있는 적절한 방법이 채용될 경우등등.
가령, 유니코드에서는 0xFEFF라는 값을 바이트 순서 표식 (Byte Order
Mark)라고 하여 자료를 읽은 쪽에서 0xFFEF라고 읽히면, 서로 가정하는
바이트 순서가 뒤집혔다고 판단, 바이트 순서를 뒤집어서 읽도록
하고 있습니다.)

유니코드와 UTF-8을 비교한 것은 16 비트 인코딩 방법으로서의
유니코드 인코딩 및 유니코드 + network byte order등을 모두 포함하고,
이들 방법과 UTF-8과 비교해 볼 때, UTF-8이 안전하고 잇점이 많다라는
것을 말하려는 의도였습니다. 그러나, 이미 RFC 2130에서 UTF-8을
표준 인코딩으로 추천하고 있더군요.


인코딩 방법으로서의 유니코드를 의미한다면 UTF-16이라고 하는 것이 더
엄밀했을 것입니다.
따라서, 제가 의도하고자 했던것을 좀 더 엄밀하게 나타낸다면,


- KS C 5601은 한글을 다 못 나타내는 등 문제가 많아 ISO 10646 문자
세트 (CCS)로 전이하여야 한다.
- 이때, 인코딩 방법으로 UTF-16이 사용될 수 있으나,
-- 바이트 순서에 문제가 발생할 수 있고,
-- 기존 아스키 문서와의 호환성이 문제가 되며,
-- 아스키 문서의 경우, 문서의 크기가 2배가 되며,
-- 아스키 기반의 기존 환경 (운영체제, 프로그램등)과 충돌하며,
-- 차후, 유니코드의 4 바이트 확장판이라고 볼 수 있는 ISO-8859
UCS-4와도 그대로 호환되는 것이 아니다.
따라서, 이와 같은 이슈가 문제가 되지 않는 경우에 해당하는
내부적인 문서의 형식 및 내부적인 처리 용도로 UTF-16을 사용하고,
이외에는, 이러한 문제를 하나도 갖지 않는 UTF-8을 사용하여
인코딩하는 것이 바람직하다.


라는 것이었습니다.



=== 자바에서의 인코딩 이름 =====


언급된 이유로, 자바에서 16 비트 인코딩 이름으로 Unicode 및 8
비트 인코딩으로서 KSC5601, EUCJIS, 8859_1, UTF8등등 여러가지가
동급으로 사용되는 것은 잘못된 게 아니라 생각됩니다.
물론, 여기서 EUC-KR을 사용하지 못하고, 대신 KSC5601을 사용해야만 하는
것은 다소 논란거리가 될 수 있습니다.
그러나, EUC-KR이 우리나라에서 폭넓게 받아들여지고 있는 인코딩 이름이라고
주장할만한 증거 문서를 대기가 곤란하여, 썬사에 bug report를 내기도
곤란하더군요.


p.s. 역시, 이런 문제를 다루는 것은 재미없군요. 또, 저 역시 이쪽
방면으로 전문 지식을 갖고 있는 것은 아니라서...


===== 참고문헌 =======
[1] http://www.globecom.net/(nobg,sv)/ietf/rfc/rfc2130.shtml
[2] ``The Unicode Standard, Version 2.0,'' The Unicode
Consortium, Addison Wesley, 1996
[3] http://www.unicode.org/unicode/standard/principles.html



Follow Ups:



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

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


[ Follow Ups ] [ Post Followup ] [ 자바 묻고 답하기 ]