普通の人はあんまり見ることはない気もしますが、IMAPでフォルダ名に日本語を使うと、BASE64みたいな、アルファベットや記号など7bitコード文字だけにエンコードされた名前になります。
あれって、IMAP-UTF7という名前のエンコーディングなんだそうです。
簡単にデコードできるツールってないかな?と思って、FreeBSDのportsの中を探してみたら、
ports/converters/p5-Unicode-IMAPUtf7/
というのがありました。
付属していたスクリプトをそっくりマネして書いただけなんですが、とりあえずテストするスクリプト。
require 'Unicode/IMAPUtf7.pm';
my $t = Unicode::IMAPUtf7->new, 'Unicode::IMAPUtf7';my @input = qw(&Tgtm+DBN- &kAFP4W4IMH8wojCkMMYw4A- &j,dg0TDhMPww6w-);
for (my $i = 0; $i < @input; $i++) {
$tmp = $t->decode($input[$i]);
print "|" . $input[$i] . "| -> |$tmp|\n";
}
実行してみる。
% perl imap-utf7.pl | nkf
|&Tgtm+DBN-| -> |下DBN-|
|&kAFP4W4IMH8wojCkMMYw4A-| -> |送信済みアイテム|
|&j,dg0TDhMPww6w-| -> |迷惑メール|
なるほど・・・
ただ、1個めのデコード結果がおかしいような。本当は「下書き」になるはずなんだけど。
nkfがおかしいのかな?と思い、iconv。
% perl imap-utf7.pl | iconv -f 'utf-8' -t euc-jp
|&Tgtm+DBN-| -> |下DBN-|
|&kAFP4W4IMH8wojCkMMYw4A-| -> |送信済みアイテム|
|&j,dg0TDhMPww6w-| -> |迷惑メール|
だめですね。
いろいろ試す。
|&Tgtm+DBN-| -> |下DBN-|
|&Tgs-123| -> |下123|
|&ZvgwTQ-| -> |書き|
|&ZvgwTw-| -> |書く|
|&Tgswa2b4ME0-| -> |下に書き|
|&Tgtm+A-| -> |下A-|
「下書」がアウトらしい・・・
ひょっとして、Unicode/IMAPUtf7.pm がおかしい???
IMAP-UTF7 ってのは正式な名前じゃないわけです。
返信削除このエンコードを定義している RFC 3501 では 「Modified UTF-7」としています。
ともあれ、そのRFCを読んでいただくと分かりますが、Modified UTF-7 には "+" は含まれません。ということで、お試しになっている文字列がそもそも、Modified UTF-7 ではないわけですが、いったいどうやって作ったものでしょうか?
Unicode::IMAPUtf7のドキュメントにはRFC2060と出てますが、
返信削除RFC3501によって、RFC2060がobsoleteになってるんですね。
IMAPサーバはimap-uwで、IMAPクライアントは、Netscape Communicator、Mozilla Thunderbird、Outlook Expressなどで、とくに文字化けなしです。
「下書き」をUTF-7でエンコードすると「+Tgtm+DBN」になるようなので、+を&に置き換えて、最後に-を追加して…
use Unicode::IMAPUtf7;
my $t = Unicode::IMAPUtf7->new();
print $t->decode('&Tgtm&DBN-') . "\n";
とすれば「下書き」に戻りました。
どういうわけか
print $t->encode('下書き');
は
+Tgtm&DBN-
になるんですが、これはdecode()しても「下書き」に戻りません。
謎が増えました…
ファイルシステム上でのファイル名がどうなるかは、IMAPサーバの実装依存という感じはしますね。
Unixで+と&といえば、「lost&found」が「lost+found」になってるのを思い出しました。
Unicode::IMAPUtf7 のソースを見てみたら・・・これはまずいでしょ。
返信削除そもそも、latin1 しか考えてないような。
Encode::IMAPUTF7 のほうがよさそう。
確認していただきありがとうございます。
返信削除うーん、そういうオチでしたか。