Computer/PHP

한글메일의 인코딩,디코딩

알찬돌삐 2012. 8. 10. 16:40

 

인터넷 한글 메일의 인코딩과 디코딩


웹 페이지 게재일 : 1998 / 04 / 10

1. 인코딩과 디코딩

1) 전자메일 서비스는 초기에 RFC 822를 기반으로 정보교환이 이루어졌으며, 이 RFC 822는 정보
교환 매체를 7비트인 US-ASCII 텍스트로 사용할 것을 제한하고 있습니다.

2) SMTP(단순 우편 전송 프로토콜)는 7비트의 길이만을 통과하므로, 8비트를 구성된 문서, 즉 8비트
를 사용 하는 유럽(독일,프랑스) 언어, 16비트를 사용하는 동양권(한국,중국,일본) 언어등에서는
msb=1인 경우 이 msb가 짤려나가므로 문제가 생깁니다.

3) 해결책으로 8비트 문자코드를 사용하는 나라에서는, 각 언어별 문자세트를 지정하고 8비트 문자
들을 7비트 영문 아스키로 변환(인코딩)한 후 전송하고, 수신측에서 이를 다시 8비트로 변환
(디코딩)하는 방법을 사용합니다.



2. 한글 메일의 인코딩 방법들

1) 한글 메일의 문제점

한글은 16비트로써 즉 8비트 2개로써 한 문자를 표현하므로, 그대로 SMTP를 통과하면 MSB(최상위
비트)가 잘려 나갑니다. 그래서 MIME 규격에 의해 전자 우편을 전송합니다.


2) MIME(다목적 인터네트 우편 확장 표준) 규격

SMTP의 데이터 포맷을 확장함으로써 텍스트는 물론 비디오, 오디오, 동화상 등의 다양한 멀티미디어
데이터를 전송할 수 있게 해주는 인터넷 메일의 확장을 의미합니다.

MIME 규격은 전자우편 메시지 상단에 있는 전통적인 SMTP 헤더에다 MIME 헤더를 추가합니다.
MIME 헤더에는 [우편물 유형, 사용된 문자세트] 및 [인코딩 방식] 등의 정보를 가집니다.

그리고, RFC822에 규정된 전통적인 SMTP 헤더는 To[발신자], From[수신자], Date[일자], Subject[제목],
Reply_To[회신자], cc[참고], message_ID 등의 정보가 있습니다. 이들이 놓이는 순서에 대한 특별한
규정은 없습니다.

3) MIME에서 정의하고 있는 전송 데이타의 Type(파일종류)/Subtype(파일포맷)

Text / Plain : 포맷되지 않는 텍스트 (특정한 문자세트로 구성됨)
Text / Richtext : 볼드, 이탤릭체, 밑줄 등 간단한 포맷을 가진 텍스트
Multipart / Mixed : 복수개의 서로 다른 유형의 데이터 본문들을 하나의 메시지로
조합

Application / Octet-Stream : Binary 데이타
Application / Postscript : PostScript 프로그램
Message / RFC 822 : 또다른 우편 메시지 RFC 822

Image / JPEG : 정지화상 데이타, ISO 10918 포맷
Image / GIF : 정지화상 데이타, CompuServe의 Graphic interchange 포맷
Video / MPEG : 동화상 데이타, ISO 11172 포맷
Audio / Basic : 오디오 데이타, 8비트 ISDN mu-law 포맷을 사용한 인코드


4) MIME의 Header Fields

1. MIME-Version : 에이전트를 지원하는 MIME 버전을 표시함.
2. Content-Type : 전송 데이타의 type/subtype[우편물 유형]과 character-set[사용된
문자세트]을 표시함.
3. Content-Transfer-Encoding : 전송 데이타의 body를 인코딩한 방법[인코딩 방식]을 표시함.
4. Content-ID : MIME 내용들을 식별하기 위한 표시 (생략가능)
5. Content-Description : 메시지 본문 내용에 대한 설명 (생략가능)


예) 한글메일 표준의 MIME 헤더인 경우 (7bit ISO-2022-KR 한글코드가 인코딩 없는 7bit 방식을 사용한 경우)
Content-Type: text/plain; charset=ISO-2022-KR, Content-Transfer-Encoding: 7bit

예) KS5601인 경우 (8bit 한글코드는 인코딩 없이 전송할 수 없으므로, 이미 수신한 것을 저장할 때만 사용함)
Content-Type: text/plain; charset=EUC-KR, Content-Transfer-Encoding: 8bit

예) 영어권인 경우 (7bit 영어문자가 인코딩 없는 7bit방식을 사용한 경우)
Content-Type: text/plain; charset=US-ASCII, Content-Transfer-Encoding: 7bit

예) 유럽언어인 경우 (8bit 유럽문자가 한 바이트를 세 바이트로 변환하는 인코딩 방식을 사용한 경우)
Content-Type: text/plain; charset=ISO-8859-1, Content-Transfer-Encoding: quoted-printable



5) MIME에서의 Content-Transfer-Encoding 방식

전송내용물 인코딩 방식은 크게 5 가지가 있습니다. 헤더에 Content-Transfer-Encoding 필드가
생략되어 있으면 7bit 방식을 의미합니다. 7bit 방식, 8bit 방식, 및 binary 방식 이들 세가지
방식들은 인코딩을 하지 않는 방식입니다.

이에 반해 Base64와 Quoted-Printable 방식은 8bit코드를 7bit코드로 인코딩하고, 다시 7bit를 8bit로
디코딩합니다. 그러므로 HTML문서를 전자메일로(SMTP로) 보낼 때나, 그래픽 파일을 첨부파일로 보낼
때에 이들 문서들은 7bit 텍스트(문자 메시지) 이외에 8bit 이미지 등을 포함하고 있으므로 Base64와
Quoted-Printable 방식 중에 하나를 사용해야 합니다. 실제로 Outlook Express는 이 두가지 중 하나로
설정되어 있음을 확인할 수 있습니다.

(1) 7bit

1) [7bit] 방식은 전자우편 메시지의 Default Format입니다.
이는 이미 7bit로 인코딩된 문자세트라고 할수 있고, 전송할 때 더 이상 인코딩하지 않습니다.

2) [7bit] 방식은 정보교환을 위해 7비트 ASCII 코드로만 전송 데이타를 표현하는 방식입니다.

3) ISO-2022란 정보교환용 부호에 관한 국제표준입니다.
특히, ISO-2022-KR이란 8비트 KSC-5601을 7비트 ISO-2022방식으로 인코드한 것을 말합니다. 즉
ISO-2022-KR은 국제적 정보교환을 위해 한글 각 글자마다 2개의 7bit 코드로 표현한 코드체계입니다.

(예) "가나 다" => ESC$)C <SO>0!3*<SI> <SO>86<SI>
; ESC$)C는 ISO-2022-KR의 시작,
; <SO>, <SI>는 각각 8비트의 시작,종료

(2) 8bit

[8bit] 방식은 ASCII 문자와 non-ASCII 문자를 포함하고 있음을 나타내고, 실제 데이타에 대한
인코딩은 하지 않습니다.

(3) Quoted-Printable

1) [quoted-printable] 방식은 msb가 1인 1바이트를 입력받아 msb=1임을 의미하는 "="와 실제
코드값에 해당하는 16진수를 문자 "0"부터 "F"까지로 표현하므로 한 바이트를 세 바이트로
인코딩하는 방식이다.

2) [quoted-printable] 방식은 QP 인코딩 이라고도 한다. 유럽권 언어에 많이 사용합니다. 한글에
적용할 경우 msb=1인 8비트가 많으므로 최고 3배까지 전송량이 증가합니다.

(예) Mu(움라이트)nchen => M=FCnchen
(예) "가나 다" => =B0=A1=B3=AA =B4=D9


(4) Base64

1) [Base64] 방식은 24비트(3바이트)를 입력받아 이를 6비트씩 잘라 4바이트를 출력하는 인코딩
방식, 각 6비트를 특정 코드 값으로 매칭시켜 변환하는 MIME 인코딩 방식입니다.

2) [Base64] 방식은 데이타 크기가 33% (1.3배)만큼 증가합니다. RFC 1113에 의한 코드 체계를
따릅니다.

(예) "가나다" (2바이트 x 3자 = 6바이트) => sKGzqrTZ (1바이트 x 8자 = 8바이트)

(5) binary

1) [binary] 방식은 SMTP에서는 한 라인에 1,000 문자를 넘지 못하도록 규정하고 있는데, 7bit와
8bit는 이를 준수합니다.

2) 그러나, [binary] 방식은 길이에 제약이 없고, 역시 실제 이진 데이터에 대한 인코딩은 하지 않
습니다.

6) HTML문서에서의 Content-Type과 Character Set

1) 전자메일은 7bit전송을 기반으로 하는 SMTP 프로토콜을 사용하지만, 이에 비해 HTML문서는 8bit전송을
기반으로 하는 HTTP프로토콜을 사용하므로 인코딩이 필요하지 않습니다. 그러므로 8bit 문자코드일지
라도 인코딩 없이 그대로 전송됩니다.

2) 다음은 HTML문서의 <head>와 </head> 태크 속에 사용된 content-type과 charset의 예입니다.
< meta http-equiv="content-type" content="text/html"; charset="euc-kr" >

여기서 HTTP는 인코딩 문제와 관계가 없으므로 8bit(실제 8bit+8bit) 한글코드인 Euc-KR이 사용되었습니다.



3. 한글메일의 표준 인코딩 방식

(1) 편지의 헤더(header) 전송

SMTP 편지헤더는 [발신자], [수신자], [송수신일시], [제목], [경로] 등 해당 편지에 대한 정보를 기록
하는 전자우편의 머리 부분입니다.

한글이 포함된 편지헤더의 인코딩은 헤더 전체를 인코딩하는 것과 한글만을 인코딩하는 것
모두 가능합니다. QP 또는 Base64 인코딩을 따르며, 한글 편지제목의 예를 들어보면
=?문자세트?인코딩방법?인코딩된 편지제목?= 와 같이 특정 형식으로 전송합니다.

[편지헤더]의 한글메일 표준은 = ? EUC-KR ? Q(또는 B) ? QP(또는 Base64)로 인코딩된 편지제목 ? = 의
형식을 가집니다. 문자세트(charset)는 EUC-KR을 사용하며, EUC-KR에서는 msb=1 이면 KSC-5601
로 인식합니다. 여기서 Q는 QP 인코딩을, B는 base64 인코딩을 의미합니다.

EUC-KR은 Extended Unix Code-Korean을 의미하며, Unix를 비롯하여 Mac, MS-DOS, Windows 환경
에서 널리 사용되고 있습니다.

(2) 편지의 본문(body) 전송

[편지본문]의 한글메일 표준은 ISO-2022-KR (7bit) 인코딩 방식을 사용합니다.



4. 한글메일이 깨지는 이유? 해결책?

(1)이유

전자우편의 전달 과정은 MUA->MTA-->MTA->MUA 입니다. MUA로는 UNIX의 Mail, Pine 등과 Windows의
Netscape Mail, Eudora, MS Outlook-Express 등이 있습니다. MTA로는 UNIX용 영문 sendmail, 한글
sendmail 등과 NT용 메일서버, 95용 메일서버 등이 있습니다.

그리고 전자우편 전송프로토콜인 SMTP가 8비트를 전송하지 못하고 7비트만을 전송하므로 8비트
데이타를 7비트로 인코딩하여 전송하면 수신측에서는 이를 다시 8비트로 디코딩하여 화면에 출력
하지요. 그런데 인코딩/디코딩 방식이 그 종류가 많아서 MUA,MTA가 이를 모두 처리하지를 못하는
경우가 많습니다. 이러한 경우 디코딩되지 않은 한글이 화면에 나타내게 되어 깨져보이지요.

또한 과거에는 MTA에서 인코딩을 지원하였으나, 최근에는 일부 MUA에서 한글 인코딩(ISO-2022-KR)
을 지원하고 있습니다. 문제는 이들이 각기 RFC 1557을 잘못 해석한 데서 이들 사이에 호환성이
없어 문제가 발생하고 있습니다. 그래서 1996.11.22일자로 한국전산원에서 RFC의 애매 모호한
규정을 재정립하여 발표한 바 있습니다.

(2)해결

해결방법은 한글메일변환 프로그램을 다운로드 받아 설치하고 이를 통해 디코딩하여 메일 내용을
보는 방법입니다. ftp://netlab.ync.ac.kr/
한후 'Internet_Utilities' 디렉토리로 가서 다시 '한글메일변환' 디렉토리로 가서 'cvt.zip' 또는
'NShmconv.exe'(넷스케이프 전용임)를 다운로드 받아 사용하세요.




5. Netscape Mail을 이용한 한글 메일

(1) MUA = Netscape 3.0(Allow 8bit 선택=EUC-KR)이고, MTA = UNIX 한글 sendmail 일 때

(인코딩)
1. Header는 Base64로 인코딩
2. Body는 ISO-2022-KR로 인코딩

(디코딩)
=> Netscape 3.0은 EUC-KR(8bit) 메일은 인식하나,ISO-2022-KR(7bit) 메일을 지원하지 않습니다.
=> ISO-2022-KR 인지 능력은 부여되어 있으므로 메일본문에 다음의 태그를 맨위에 붙인 후 html
=> 파일로 저장한 후 파일 열기하여 보면 메일을 볼수는 있으나, Netscape의 버그로 깨지는 부분이
=> 있을 수 있습니다. 그래서 한글메일변환 프로그램을 사용하여 메일을 보는 방법을 즐겨 씁니다.
=> <META HTTP-EQUIV="Centent-type" CONTENT="text/html"; CHARSET=ISO-2022-KR>


(2) MUA = Netscape 3.0(MIME(QP), Korean선택)이고, MTA = UNIX 한글 sendmail 일때

(인코딩)
1. Header는 Base64로 인코딩
2. Body는 QP로 인코딩

(디코딩)
=> 편지 headre는 잘 인식하나, MIME을 인식하지 못하는 UNIX mail reader들은 편지 body를 읽지 못합니다.
=> Pine3.93이상, Netscape 3.0이상, Eudora, MS Exchange는 편지 body를 읽습니다.

(3) MUA = Netscape 4.0이고, MTA = UNIX 한글 sendmail 일때

(인코딩)
1. Header는 Base64로 인코딩
2. Body는 ISO-2022-KR로 인코딩

(디코딩)
=> Netscape 4.0은 ISO-2022-KR(7bit) 메일을 지원하므로 이 표준 한글메일이면 다른 수단 없이
=> 한글메일을 잘 볼수 있습니다 !!!
=> 그 이전 버전에서 ISO-2022-KR을 KSC5601로 변환해 주기 위해 사용되는 툴이 불필요합니다.



6. 참고

(1) RFC 822 : 정보전송 매체를 7비트인 US-ASCII 텍스트에 제한하고 있는 전자메일 서비스입니다.

(2) RFC 1522 : MIME 규정입니다.

기존 7비트 인터넷 메일 시스템에서 8비트 전송을 보장하기 위해 MIME 헤더를 사용합니다.
헤더 부분의 한글은 B 또는 Q 인코딩을 사용하며, 문자세트는 EUC-KR을 사용합니다.

헤더에 한글이 포함되어 있는 경우, 헤더 전체를 인코딩하는 것과 한글만을 인코딩하는
것 모두 가능합니다. 파일이름과 같이 하나의 토큰으로 인식해야 하는 경우, 헤더 전체를
인코딩해야 합니다.

(3) RFC 1557 : 문자세트와 인코딩의 지정, Designator와 공백문자의 처리방법에 대한 규정입니다.

7비트로 인터넷 한글메일을 교환하기 위해 한글메일은 Character Set에 "ISO-2022-KR"을
사용하고 인코딩은 "7bit"를 명시합니다.
ESC$)C로 ISO-2022-KR의 시작을 알리는 Designator는 최초로 한글이 나타나기 전, 본문의
임의의 위치의 제일 첫칸에 명시되어야 합니다.

이 글은 스프링노트에서 작성되었습니다.

.