IT/Tips

일본어 메일 보내기

싸후이 2007. 4. 24. 17:34
일본어 메일은 반드시 JIS코드로 송신해야합니다.
메일 해더의 캐릭터셋은 ISO-2022-JP로 합니다.
일본어가 들어간 송신자이름, 수신자이름, 제목, 파일명은 반드시
ISO-2022-JP코드로 64B인코딩해야합니다.
(예,Subject: =?ISO-2022-JP?B?GyRCI1cjRSNCRVBPPyROJCpDTiRpJDsbKEI=?=)
RFC규정에 Quoted Printable 인코딩 방법이 있는데 이 인코딩 방법은
일본어 메일 헤더내에 절대로 사용하지 않아야 합니다. 의외로 이 인코딩
방법을 쓰는 메일들을 많이 봅니다. 많은 클라이언트 메일러에서
이 인코딩 방법을 지원하지 않습니다. 그리고 I-MODE등의 휴대전화로
메일을 보냈을때 여지 없이 깨어집니다. 많은 비지네스맨들이
메일을 휴대전화로 전송하여 확인하고 있다는 사실을 염두해야 합니다....
Shift_JIS코드로 아무 처리없이 그냥 메일을 보내지 말아야 합니다.
일부 메일러에서는 처리해주는 경우가 있으나 아직도 미비합니다.
이렇게 보내지는 메일도 많이 보아 왔습니다.휴대전화에서는 깨짐.
가급적이면 Content-type: text/html; 을 사용하지 않는다. 대부분의
PC에서는 지원이 되나 휴대전화에서 지원하지 않아 많은 사람들이
짜증을 냅니다. 이 콘텐트 타이프를 사용하고자 할때는
Content-Type: multipart/alternative; 를 사용합니다.
이 때에는 처음 텍스트 파트는
------=_NextPart
Content-Type: text/plain;
    charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit
와 같은 방법으로 그냥 JIS코드로 본문을 작성합니다.
JIS코드는 ISO에 등록된 7bit코드라서 위와같이 지정합니다.
다음 HTML파트는
------=_NextPart
Content-Type: text/html;
    charset="iso-2022-jp"
Content-Transfer-Encoding: quoted-printable
와 같은 방법으로 여기에서는 quoted-printable를 사용합니다.
일반적으로 64인코딩을 하는 경우도 있는데 일부 메일러와
휴대전화에서 지원하지 않습니다. 위와 같이 처리하면
휴대전화에서도 HTML로 송신된 메일을 받아볼 수 있습니다.
무작정 전부다 64인코딩이나 Q인코딩하지 말아야 합니다.
일부 텍스트 메일과 위의 multipart/alternative타입의 경우
메일 본문을 모두 64인코딩이나 Q인코딩하는 사례 역시 많이
발견합니다만, 휴대전화에서는 지원하지 않고 일본어 메일러에서
지원하지 않는 경우가 있습니다.
Content-Type: multipart/mixed; 의 경우도 위와 같은 방법으로
헤더와 메일 본문을 작성합니다.(아래 소스 참조)
(다 알고 있는 부분이겠지만...)
korea.internet.com의 경우 Content-Type: multipart/alternative; 를
사용하여 메일을 송신하고 있는데 위의 텍스트 부분은 64인코딩을하고
HTML부분은 Q인코딩하여 송신을 합니다. 이것은 한글의 완성형
euc-kr이나 ks_c_5601-1987은 8bit 코드 라서 텍스트 부분을 RFC규정에
준하여 64인코딩을 해주는 겁니다. 물론 이렇게 안해줘도 한국에서는
메일이 잘 전달이 됩니다. 요즈음은 거의 안 쓰이지만 이전의 7bit
ISO 한글코드를 사용하면 64인코딩을 하지 않아도 된다는 이야기 입니다.
이렇게 인코딩을 하는 것은 일부 메일 서버에서 아직도 8bit메일을 통과
시키지 못하는 경우가 가끔 있기 때문입니다.
<?php
function jpmail ($from_mail, $from_name, $to, $subject, $body, $attach, $filename)
{
$boundary = "____nogada" . uniqid("b");
$from_name = '=?ISO-2022-JP?B?'.base64_encode(euc2jis($from_name).'?=';
###입력값이 Shift_JIS 코드일때
//$from_name = '=?ISO-2022-JP?B?'.base64_encode(sjis2jis($from_name).'?=';
$from = $from_name." <".$from_mail.">";
   
### 제목을 jis(iso-2022-jp)코드로 변환해서 MIME 인코딩한다.
$subject   = '=?ISO-2022-JP?B?'.base64_encode(euc2jis($subject)).'?=';
###입력값이 Shift_JIS 코드일때
//$subject   = '=?ISO-2022-JP?B?'.base64_encode(sjis2jis($subject)).'?=';
### 본문을 jis코드로 변환한다.
$body      = euc2jis($body);
###입력값이 Shift_JIS 코드일때
//$body      = sjis2jis($body);
$body  = str_replace("rn", "n", $body);
$body  = str_replace("r",   "n", $body);
### 첨부할 파일 데이터를 base64 인코딩 한다.
$attach = base64_encode($attach);
### 파일명을 jis( iso-2022-jp)코드로해서 MIME 인코딩한다.
$filename = '=?ISO-2022-JP?B?'.base64_encode(euc2jis($filename).'?=';
###입력값이 Shift_JIS 코드일때
//$filename = '=?ISO-2022-JP?B?'.base64_encode(sjis2jis($filename).'?=';
### 메일 송신
$sendmail = '/usr/sbin/sendmail';
   
$MAIL = popen("$sendmail -f $from_mail $to", "w");
###송신자의 메일어드레스가 없어도 송신이 가능한 경우
//$MAIL = popen("$sendmail -t -f $to", "w");
 
########################## 메일 데이타 작성
### 본문 헤더
fputs($MAIL, "From: $fromn");
fputs($MAIL, "To: $ton");
fputs($MAIL, "Subject: $subjectn");
fputs($MAIL, "MIME-Version: 1.0n");
fputs($MAIL, "Content-Type: Multipart/Mixed;n");
fputs($MAIL, "    boundary="$boundary"n");
fputs($MAIL, "n");
### 메일 본문 파트
fputs($MAIL, "This is a multi-part message in MIME format.n");
fputs($MAIL, "n");
fputs($MAIL, "--$boundaryn");
fputs($MAIL, "Content-Type: text/plain;n");  
fputs($MAIL, "    charset="ISO-2022-JP"n");
fputs($MAIL, "Content-Transfer-Encoding: 7bitn");
fputs($MAIL, "n");
fputs($MAIL, "$bodyn");
### 첨부파일 파트
fputs($MAIL, "--$boundaryn");
fputs($MAIL, "Content-Type: application/octet-stream;n");
fputs($MAIL, "    name="$filename"n");
fputs($MAIL, "Content-Transfer-Encoding: base64n");
fputs($MAIL, "Content-Disposition: attachment;n");
fputs($MAIL, "    filename="$filename"n");
fputs($MAIL, "n");
fputs($MAIL, "$attachn");
fputs($MAIL, "n");
### 멀티 파트 끝 
fputs($MAIL, "--$boundary" . "--n");
pclose($MAIL);
}

###Shift_JIS코드를 JIS코드로 변환
function sjis2jis(&$sjis_string)
{
    $jis_code = '';
    $c = 0;
    $b = unpack("C*", $sjis_string);
    $n = count($b);
    $esc = array(chr(0x1B).chr(0x28).chr(0x42),
                 chr(0x1B).chr(0x24).chr(0x42),
                 chr(0x1B).chr(0x28).chr(0x49));
    for ($i = 1; $i <= $n; $i++) {
        $b1 = $b[$i];
        if (0xA1 <= $b1 && $b1 <= 0xDF) {
            if ($c != 2) {
                $c = 2;
                $jis_code .= $esc[$c];
            }
            $jis_code .= chr($b1 - 0x80);
        } elseif ($b1 >= 0x80) {
            if ($c != 1) {
                $c = 1;
                $jis_code .= $esc[$c];
            }
            $b2 = $b[$i+1];
            $b1 <<= 1;
            if ($b2 < 0x9F) {
                if ($b1 < 0x13F) $b1 -= 0xE1; else $b1 -= 0x61;
                if ($b2 > 0x7E)  $b2 -= 0x20; else $b2 -= 0x1F;
            } else {
                if ($b1 < 0x13F) $b1 -= 0xE0; else $b1 -= 0x60;
                $b2 -= 0x7E;
            }
            $jis_code .= chr($b1).chr($b2);
            $i++;
        } else {
            if ($c != 0) {
                $c = 0;
                $jis_code .= $esc[$c];
            }
            $jis_code .= chr($b1);
        }
    }
    if ($c != 0) $jis_code .= $esc[0];
    return $jis_code;
}
 
###일본어 EUC코드를 JIS코드로 변환
function euc2jis(&$euc_string)
{
    $jis_code = '';
    $c = 0;
    $b = unpack("C*", $euc_string);
    $n = count($b);
    $esc = array(chr(0x1B).chr(0x28).chr(0x42),
                 chr(0x1B).chr(0x24).chr(0x42),
                 chr(0x1B).chr(0x28).chr(0x49));
    for ($i = 1; $i <= $n; $i++) {
        $b1 = $b[$i];
        if ($b1 == 0x8E) {
            if ($c != 2) {
                $c = 2;
                $jis_code .= $esc[$c];
            }
            $jis_code .= chr($b[$i+1] - 0x80);
            $i++;
        } elseif ($b1 > 0x8E) {
            if ($c != 1) {
                $c = 1;
                $jis_code .= $esc[$c];
            }
            $jis_code .= chr($b1 - 0x80).chr($b[$i+1] - 0x80);
            $i++;
        } else {
            if ($c != 0) {
                $c = 0;
                $jis_code .= $esc[$c];
            }
            $jis_code .= chr($b1);
        }
    }
    if ($c != 0) $jis_code .= $esc[0];
    return $jis_code;
}
?>

###메일 송신 테스트 샘플
<?
$from_name = 坂本
$from_mail = "my@sendmail.com";
$to = "your@testmail.com";
$subject = "日本語題名";
$body = "これは日本語の本文です.";
$attach_data   = "これは添付ファイルです.n";
$attach_data .= "添付ファイルはバイナリデ-タの場合もあります.n";
$filename = "日本語ファイル.txt";
jpmail( $from_mail, $from_name, $to, $subject, $body, $attach_data, $filename);

'IT > Tips' 카테고리의 다른 글

ftp proxy howto  (0) 2007.04.26
메일 보내기  (0) 2007.04.24
Doxygen Quick Guide  (0) 2007.04.21
Change the color for Linux prompt  (0) 2007.04.05
telnet negotiation  (0) 2007.03.21