ミライハック
  • Home
  • Categories
  • About

>> Home / インターネット

sendmail、qmail、Postfixで改行なし長文メールで文字化けする問題の解決法

∵ Takayoshi Saito ∴ 2013-03-19 ∞ 2'

1000バイトを超える改行なしメールは送信できない

RFC2821によって、1000バイトを超えるメールに関しては以下の制限があります。

text line(テキスト行)>CRLF/\>/ を含むテキスト行の最大長は、1000 文字である(透過処理のために二重化された先頭のドットは含まない)。この値は SMTP サービス拡張により増やされても良い。

このため、sendmailであれ、qmailであれ、Postfixであれ、どのMTAでメールサーバーを構築しても1000バイトを超えるメールを送ろうとすると強制改行が入り、日本語などマルチバイト文字列を使っている場合は、改行が挿入された場所によっては文字化けが発生します。

解決策

RFCではSMTPサービス拡張により修正されても良いという書き方をしていますが、現在、この解決策を採用しているMTAはありません。そのため、もしスクリプトなどで1000バイトを超える未改行の文字列を受け取り、それをメール送信したいと思うならば、文字コードに合わせて適切な場所で改行を挿入するべきです。以下、Perlで各文字コード別に解決策を列挙します(参考:sendmail が勝手に改行コードを挿入する件)。

UTF-8での対策

 

sub fold {
my ($str, $n) = @_;
my $ret = "";
my $len = 0;

# 指定無き場合、200文字で折り返す
$n ||= 400;
while($str =~ m{([\n]) | # 改行コード
([\x00-\x7F]) | # 1byte

(|[\xc0-\xdf][\x80-\xbf]) | # 2byte
([\xe0-\xef][\x80-\xbf][\x80-\xbf]) |
([\xf0-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]) |
([\xf8-\xfb][\x80-\xbf][\x80-\xbf][\x80-\xbf][\x80-\xbf]) |
([\xfc-\xfd][\x80-\xbf][\x80-\xbf][\x80-\xbf][\x80-\xbf][\x80-\xbf]) |

.}gx) {
if (defined $1) { $ret .= $1; $len = 0 };
if (defined $2) { $ret .= $2; $len++ };
if (defined $3) { $ret .= $3; $len += 2 };
if ($n &<= $len) { $ret .= "\n"; $len = 0 }
}
chomp $ret;
$tbody = $ret;
}

EUC-JPでの対策

sub fold {
my ($str, $n) = @_;
my $ret = "";
my $len = 0;

# 指定無き場合、200文字で折り返す
$n ||= 400;
while($str =~ m{([\n]) | # 改行コード
([\x00-\x7F]) | # 1byte
([\x8E¥xA1-\xFE][\xA1-\xFE]) | # 2byte
.}gx) {
if (defined $1) { $ret .= $1; $len = 0 };
if (defined $2) { $ret .= $2; $len++ };
if (defined $3) { $ret .= $3; $len += 2 };
if ($n &<= $len) { $ret .= "\n"; $len = 0 }
}
chomp $ret;
return $ret;
}

Shift-JISでの対策

sub fold {
my ($str, $n) = @_;
my $ret = "";
my $len = 0;

# 指定無き場合、200文字で折り返す
$n ||= 400;
while($str =~ m{([\n]) | # 改行コード
([\x00-\x7F\xA1-\xDF]) | # 1byte
([\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]) | # 2byte
.}gx) {
if (defined $1) { $ret .= $1; $len = 0 };
if (defined $2) { $ret .= $2; $len++ };
if (defined $3) { $ret .= $3; $len += 2 };
if ($n &<= $len) { $ret .= "\n"; $len = 0 }
}
chomp $ret;
return $ret;
}
Search

Categories
  • LInux
  • インターネット
  • インフラ
  • エッセイ
  • ゲーム
  • システム開発
  • セキュリティ
  • データサイエンス
  • 国際関係
  • 政治
  • 歴史
  • 社会学
  • 自己紹介
  • 行ってきた

Pages
  • 齊藤貴義
  • 職務経歴
  • スクレイピング・ハッキング・ラボ サポートページ
  • 『爆速開発を支えるClaude Code上級者テクニック』サポートページ

2026 © Takayoshi Saito | Twitter GitHub | Built on Zola