I'm on your side, when times get rough.

2009-02-11

Detecting Multi-Language Codepage #1

Filed under: Programming — Peter_KIM @ 10:40

가끔 다른 나라의 인터넷 사이트를 항해하다 보면, 다음과 같은 경우를 겪을 것입니다.

 

한 국가의 언어에 최적화된 윈도우 운영체제에서 다른 국가의 문자로 표시된 언어의 텍스트를 읽는다는 것이 그다지 쉬운 일은 아닐 것입니다. 다행스럽게도 텍스트 파일이 ANSI 형식이 아닌, 유니코드 형식으로 저장 되어있다면, 메모장(Notepad.EXE) 같은 프로그램으로 읽는데 크게 문제가 없을 수도 있습니다. 그러나, 모든 윈도우 운영 체제에서 제공하는 메모장 프로그램이 항상, 유니코드 형식으로 저장된 다른 국가의 언어로 저장된 텍스트를 잘 읽을 수 있는 것은 아닙니다.

기본적으로 운영체제에서 다른 나라의 문자를 표시하려면, 해당 국가의 언어를 지원하는 프로그램(Language Pack)을 설치해야 합니다.

한국어 윈도우 운영체제(Windows 2000)의 메모장에서 중국어 간체로 저장된 텍스트를 표시하면, 아래처럼 보일 것입니다.

 

ANSI, Unicode 형식으로 저장된 모든 문서가 제대로 표현되지 않습니다. 윈도우에서 생성되는 대부분의 유니코드 텍스트 파일의 시작 부분에는 BOM(Byte Order Mark) 설정이 되어 있습니다. 이 부분을 확인하면, 파일의 인코딩 값을 알 수 있습니다.

MSDN 사이트에는 다음과 같은 내용의 글이 있습니다.

텍스트 파일의 인코딩을 효율적으로 감지하는 방법
임의의 ANSI 코드 페이지를 효율적으로 감지할 수 있는 방법은 없지만 텍스트 중간에 특정 바이트 시퀀스가 있을 확률에 따라 이 작업을 수행하려는 시도는 있었습니다. StreamReader에서는 이 작업을 수행하지 않습니다. XML이나 HTML과 같이 웹 브라우저, 데이터베이스 및 XmlTextReader 등의 클래스에서 이러한 파일을 정확하게 읽을 수 있도록 해당 파일의 첫 번째 줄에 있는 문자 집합을 특정 방식으로 지정하는 파일 형식도 있지만 대다수의 텍스트 파일에는 이러한 유형의 정보가 기본적으로 포함되어 있지 않습니다.

대신 유니코드 표준이 단일 코드 포인트(U+FEFF)를 유니코드 바이트 순서 표시(BOM)로 정의합니다. big 또는 little endian 바이트 순서의 UTF-16 형식으로 저장된 파일이 있는 경우 해당 파일의 처음 2바이트가 FE FF 또는 FF FE이면 해당 파일은 UTF-16 텍스트 파일인 것으로 볼 수 있고 바이트 순서를 지정할 수 있습니다. UTF-8은 UTF-16과 같이 바이트 순서 문제가 발생하지는 않지만 이 유니코드 BOM을 통해 해당 파일이 UTF-8 텍스트임을 추측할 수 있습니다. 이론상으로는 다른 인코딩들도 일부 자주 사용되는 접두사를 정의할 수 있습니다.

또 다른 예로, 아라비아(UTF-16, codepage: 1200) 문자가 저장된 텍스트 파일을 Windows XP SP3(English) 운영 체제에서 “메모장”와 “Internet Explorer”를 이용하여 읽어보았습니다. “메모장”은 잘 표시하지 않았지만, “Internet Explorer”는 해당 국가의 문자를 잘 표시합니다.

 

운영체제에 언어 지원(Language Pack)이 설치되어 있더라도, “메모장”은 그 자원을 사용하지 않으므로, 위의 그림과 같은 결과가 나타나는 것입니다. 또, 유니코드로 저장되었더라도 BOM 부분이 없거나 손상된 경우 대부분의 프로그램은 문자열을 제대로 표시하지 못할 수도 있습니다.

응용 프로그램이나 시스템 프로그램 개발을 하다 보면, 이런저런 이유로 다국어 지원을 필수로 할 경우가 많습니다. 그리고, 여러 나라의 문자들을 제대로 표시하여야 할 경우도 있습니다. 그러나, 모든 문서가 유니코드로 저장되어 있지 않을 것입니다. Windows 운영 체제가 아닌 시스템에서는 ANSI 형식으로 저장되는 경우가 많을 것입니다. 또, BOM 설정이 되지 않은 경우도 있을 수 있습니다.

본론에서 기술하는 내용은 다국어로 표시된 텍스트 파일을 읽고, 해당 파일에 적용된 Codepage 값을 알아보는 기법입니다. 모든 것을 완벽하게 처리하려면 고도의 기술과 노력이 필요합니다만, 완벽하지 않다는 것을 먼저 밝히고 시작해야겠습니다.

Windows 운영 체제에서 제공되는 Win32 API 함수에는 유용한 것들이 매우 많은데, 이 기능을 이용하면, 우리가 하려는 것을 프로그램으로 구현할 수 있습니다.

앞으로 사용할 함수는 IsTextUnicode, DetectCodepageInIStream 입니다. 각각의 함수에 대한 설명은 MSDN 사이트를 참조하십시오. 단, 이 함수들의 기능은 제한적일 수 있습니다. IsTextUnicode 함수는 매우 제한이 많아서, 이런 함수가 필요하냐는 사람도 있을 지경입니다. 오직 BOM 설정의 유무를 떠나서 유니코드(UTF-16 Little Endian) 형식의 파일을 점검할 수 있습니다.

DetectCodepageInIStream 함수는 BOM 설정이 없거나, 손상된 유니코드 파일에 대한 점검 결과를 보장 받을 수 없습니다. 그러므로, 우리의 솔루션도 다음의 경우는 처리 대상 파일에서 예외로 합니다.

1. BOM 부분이 손상된 모든 유니코드 파일
2. BOM 설정이 되어 있지 않은 유니코드 파일 (UTF-16 LE, UTF-8 제외)

Codepage 관련 참고: http://msdn.microsoft.com/en-us/library/system.text.encodinginfo.codepage.aspx

일단 여기까지 “자동으로 텍스트의 Encoding 정보를 알아내기” 서론을 마치겠습니다.

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Create a free website or blog at WordPress.com.