メール送信時に日本語をサブジェクトに書いて送るには、この部分は Base64 にエンコードした JIS でなければならない。要は、見た目が
Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJE4lRiU5JUgkRyQ5GyhC?=
のようにBase64 でエンコードされていることである。
それでは Perl でサブジェクトを Base64 処理してメールを送るにはどうしたらいいだろう?ズバリ、「
Base64エンコード・デコードする」が詳しい。より具体的には、リンク先のページを少し下にいったところの、add_econde_word という関数である。しかしこのモジュールは jcode.pl を使う。
Perl 5.8 以上であれば、use Encode; とできそうだが、このモジュール、個人的にはあまり完成度が高くないと思っている。完成度なら Unicode::Japanese の方がスマートだし使いやすい。従って以下にjcode.pl の部分を、Unicode::Japanese で置き換えた例を示す。
使用するクラス
use Unicode::Japanese;
use MIME::Base64;
#!/usr/bin/perl
use Unicode::Japanese;
use MIME::Base64;
sub add_encode_word {
my($str, $line) = @_;
my $result;
my $ascii = '[\x00-\x7F]';
my $twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]';
my $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
# この次の while 以下は EUC の文字列を対象に処理することになっているため
$str = Unicode::Japanese->new($str, 'auto')->euc;
while (length($str)) {
my $target = $str;
$str = '';
if (length($line) + 22 + ($target =~ /^(?:$twoBytes|$threeBytes)/o) * 8
> 76) {
$line =~ s/[ \t\n\r]*$/\n/;
$result .= $line;
$line = ' ';
}
while (1) {
# EUC を JIS に直す
$target = Unicode::Japanese->new($target, 'euc')->jis;
my $encoded = '=?ISO-2022-JP?B?' .
encode_base64($target, '') . '?=';
if (length($encoded) + length($line) > 76) {
$target =~ s/($threeBytes|$twoBytes|$ascii)$//o;
$str = $1 . $str;
} else {
$line .= $encoded;
last;
}
}
}
$result . $line;
}
print add_encode_word('サブジェクトのテストです', 'Subject: ');
1;
これを実行すると、以下の文字列が得られる。
Subject: =?ISO-2022-JP?B?GyRCJTUlViU4JSclLyVIJE4lRiU5JUgkRyQ5GyhC?=
わざわざ Subject: というヘッダを含めて add_encode_word 関数に渡している理由は、メールの場合は Subject: ヘッダに日本語が来る場合、Base64 でエンコードするにしても
1行は 76バイト以内と決まっているためで、この 1行とは、ヘッダ名の Subject: 自体の文字数(9バイト)を勘案する必要があるためだ。
トラックバック URL:
https://perltips.twinkle.cc/trackback/111