Linuxコマンド nkf

メールのソースを見ると以下のようになってます。

メールを送信する際、日本語というかマルチバイトは使えないのでエンコードする必要あり。

日本語の文字に変換したい場合は nkf などで MIME 形式に変換(エンコード)した文字列を入れる必要があります。

=???<エンコードされたヘッダ文字列>?=

文字コード(Chrset):ISO-2022-JP

ISO-2022-JP(JISコード)がとは

欧米様式の7ビット規格のサーバやソフトを経由したら、1ビット分が破棄されるという事態になることがあります。これが、「文字化け」という現象です。(もし文字化けメールを受け取ったら、相手のメーラーの設定を確認してもらいましょう)そこで、この現象を避けるために、日本語の文字コードでも7ビットコードを使う方法が考え出されました。

エンコード・デコード(method):BASE64

※BASE64ならB、Quoted-PrintableならQ

要するに、メーラーはISO-2022-JPの文字コードを使ってBASE64にてエンコードをしてメール送信しています。

Base64 encode/decodeする方法

•nkf -mB, nkf -MB
•perl MIME::Base64::encode_base64/decode_base64

色々なやり方があります。

iso-2022-jp用のエンコード/デコード

エンコード

$ echo 日本語テスト | nkf -W -M -j
=?ISO-2022-JP?B?GyRCRnxLXDhsJUYlOSVIGyhC

※端末の設定はUFT-8。nkfのデフォルトの出力は-jのJIS出力なので-j,-Jオプションはいらないかもしてません。

メーラで件名を”日本語テスト”にして送信、受信したメールのヘッダを確認

Subject: =?ISO-2022-JP?B?GyRCRnxLXDhsJUYlOSVIGyhC?=

※”=? ~~ ?=”に囲まれた部分がBase64エンコードされた同じ文字列になっていることを確認

デコード

$ echo GyRCRnxLXDhsJUYlOSVIGyhC | nkf -J -mB -w
日本語テスト

ちなみに、UTF-8の文字コードの場合

エンコード

$ echo 日本語テスト | nkf -W -M -w
=?UTF-8?B?5pel5pys6Kqe44OG44K544OI

メーラで件名を”日本語テスト”にして送信、受信したメールのヘッダを確認。
Subject: =?UTF-8?B?5pel5pys6Kqe44OG44K544OI?=

デコード

$ echo 5pel5pys6Kqe44OG44K544OI | nkf -W -mB -w
日本語テスト

subject.txt に「空白のタイトルです」と記載する。

$ nkf -M ./subject.txt
=?ISO-2022-JP?B?GyRCNnVHciROJT8lJCVIJWskRyQ5GyhC?=

.procmailrc には以下のように書き換えて使えばタイトルが日本語となります。

| /usr/bin/formail -i “Subject: =?ISO-2022-JP?B?GyRCNnVHciROJT8lJCVIJWskRyQ5GyhC?=”

referereの日本語を完全に表示させる

Apacheのログを見ていると検索エンジンからやってきているログが見えます。
例えばこんな感じ

http://google.yahoo.co.jp/bin/query?p=%a5%b5%a1%bc%a5%d0%b9%bd%c3%db+telnet&b=60&hc=0&hs=0

なんて書いてあるんだろう?
これをそのままブラウザに貼り付けるとその答えが見えます。
さてこれを日本語に変換してみたいと思います。

ここにある様な %xx という表記の繰返しは、URLエンコードという手順で変換されています。これをデコードします。

require ‘jcode.pl’; jcode.plを使って変換するので、フルパス指定するか、同じディレクトリに置きます

$moji = “http://google.yahoo.co.jp/bin/query?p=%a5%b5%a1%bc%a5%d0%b9%bd%c3%db+telnet&b=60&hc=0&hs=0”;
$moji =~ s/+/ /g; まず + を半角スペースに変換します
$moji =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack(“C”,hex($1))/eg; %付きの16進数の文字列2桁を、ぜんぶ数値にします。
$moji = jcode::convert(*moji,’sjis’,’euc’); これで日本語に変換

jcode.plが変換をしてくれるので楽ですね。上記の例では 「サーバー構築 telent」 という文字です。

さて、ここまではよくあるパターンです。
この変換で、デコード出来ずに化けてしまうものが時々みられます。
よく見るとデコード出来ない文字は、UTF-8 というコードがつかわれているみたいですね。

http://www.google.co.jp/search?q=%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E6%A7%8B%E7%AF%89%E8%A8%98%E9%8C%B2&ie=UTF-8&oe=UTF-8&hl=ja&lr=

さて、これはなんでしょう?
jis , sjis , euc ,などとは異なる別のコードでUTF-8というものです。というわけで、もう一段変換が必要になりました。

このコンバーターを作ろうとしましたががなかなか思い通りにいってくれないので、jcode.plみたいな既存のモジュールを使って解決をすることにします。

jcode.pmというperl向けモジュールを使います。

http://openlab.ring.gr.jp/Jcode/index-j.html

ここからモジュールをダウンロードし、以下の操作

(download Jcode-0.80.tar.gz or Jcode-0.80.zip. )

$ gunzip Jcode-*.tar.gz | tar xf –

(又は tar zxf Jcode-0.10.tar.gz) ・・・私はこちらで実施

$ cd Jcode-*
$ perl Makefile.PL
$ make
$ make install

これで完成。

前のコードを次のように書き換えて

use Jcode; ここを変更
$moji = “http://www.google.co.jp/search?q=%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E6%A7%8B%E7%AF%89%E8%A8%98%E9%8C%B2&ie=UTF-8&oe=UTF-8&hl=ja&lr=”;
$moji =~ s/+/ /g;
$moji =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack(“C”,hex($1))/eg;
$moji=jcode($moji)->sjis; ここを変更。ここの部分でほとんどのコードを変換してくれます

jcode.plの変換機能も網羅しているのでこれは便利です。
ちなみに上記の例では「サーバの構築記録」です。

これで表示は完璧!  (と思いきや、まだ化けるデータが一つだけ出てきました。それは無視だな)。

このまだ化けるデータが何なのかわかりました。
jcode.pmがUTF-8を認識できていないパターンがあるみたいです。
URLエンコード中に+記号、すなわちスペースが入っていると何らかのタイミングがあるのでしょうか、化けます。
だからUTF-8を見つけたら意図的にコード指定をしてしまいます。

あともう一つ、URLエンコードでは%がついてくるのが普通ですが、本日x(小文字のエックス)が%の代りに使われているものがありました。
この際だからまとめて変換だ。
上記のコードを更に改造して次のようにします。

use Jcode;
$moji = “http://www.google.co.jp/search?q=%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E6%A7%8B%E7%AF%89%E8%A8%98%E9%8C%B2&ie=UTF-8&oe=UTF-8&hl=ja&lr=”;
$moji =~ s/+/ /g;
$moji =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack(“C”,hex($1))/eg;
$moji =~ s/x([0-9A-Fa-f][0-9A-Fa-f])/pack(“C”,hex($1))/eg;  xも%と同じ扱いにする為に列挙
if($moji =~ /utf-8/i) { ここで utf-8の文字をチェックして
$moji=jcode($moji,’utf8′)->sjis; utf-8があるなら、utf-8からsjisへの変換を指定する
}else{
$moji=jcode($moji)->sjis; それ以外は自動変換に任せる
}

これで今度こそ完璧!

更に補足:%の代わりにxが使われているものがあるのでその対策を書きましたが、excelなど偶然にも xのあと2桁が16進数になっているキーが該当してしまいました。だから削除しておきます。

UTF-32Bへの変換

nkf -w32 –overwrite ***.py

-s sjis
-w utf-8
-e euc
-j JISコード(ISO-2022-JP)JIS 7 bit (DEFAULT)

nkf –guess

Line notifyで使いました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です