2015年5月10日

nkfとiconvの差異

JIS系文字コードとUnicodeとの変換によく使われるnkfとiconvの変換にどれくらい違いがあるのか調べてみました。

EUC-JIS-2004とShift_JIS-2004のファイルをそれぞれUTF-8に変換して、その結果を比較します。

nkf Network Kanji Filter
http://sourceforge.jp/projects/nkf/

libiconv
http://www.gnu.org/software/libiconv/

変換元となるファイルについては、プロジェクトX0213の「JIS X 0213とUnicodeの対応表」から、文字付き版のファイルを使用しました。

JIS X 0213とUnicodeの対応表
http://x0213.org/codetable/

EUC-JIS-2004とUnicodeの対応表 文字付き版
http://x0213.org/codetable/euc-jis-2004-with-char.txt

Shift_JIS-2004とUnicodeの対応表  文字付き版
http://x0213.org/codetable/sjis-0213-2004-with-char.txt


今回使用した環境、バージョンは以下の通りです。

  • cygwin 2.0.2 (0.287/5/3)
  • gcc 4.9.2
  • nkf 2.1.3
  • libiconv 1.14

ちなみにJIS X 0213のサポートは、nkfでは2.1.3から、libiconvではおそらく1.8(?)からのようです。


    ビルド

    まず、それぞれをビルドします。

    nkf 2.1.3 をビルド。

    $ tar zxf nkf-2.1.3.tar.gz 
    $ cd nkf-2.1.3
    $ make

    libiconv 1.14 をビルド。EUC-JIS-2004とShift_JIS-2004を使えるようにするため、オプション --enable-extra-encodings を指定します。 

    $ tar zxf libiconv-1.14.tar.gz
    $ cd libiconv-1.14
    $ ./configure --enable-extra-encodings
    $ make

    EUC-JIS-2004

    次に、EUC-JIS-2004の変換をします。

    nkf
    JIS X 0201 片仮名を JIS X 0208 片仮名に変換しないように、オプション -x を指定します。

    $ nkf-2.1.3/nkf -x --ic=EUC-JIS-2004 --oc=UTF-8 euc-jis-2004-with-char.txt > euc-jis-2004-nkf.txt

    iconv
    $ libiconv-1.14/src/iconv_no_i18n -f EUC-JIS-2004 -t UTF-8  euc-jis-2004-with-char.txt > euc-jis-2004-iconv.txt

    それぞれの出力ファイルを比較します。

    $ diff  euc-jis-2004-nkf.txt euc-jis-2004-iconv.txt
    204c204
    < ‾     0xA1B1  U+203E  # OVERLINE      Windows: U+FFE3
    ---
    >  ̄    0xA1B1  U+203E  # OVERLINE      Windows: U+FFE3
    266c266
    < ¥     0xA1EF  U+00A5  # YEN SIGN      Windows: U+FFE5
    ---
    > ¥    0xA1EF  U+00A5  # YEN SIGN      Windows: U+FFE5

    EUC-JIS-2004の変換では、2つの文字で異なる変換結果が得られました。

    • オーバーライン (0xA1B1)
      • nkf   U+203E
      • iconv   U+FFE3
    • 円記号 (0xA1EF)
      • nkf   U+00A5
      • iconv   U+FFE5

    Shift_JIS-2004

    次に、Shift_JIS-2004の変換をします。

    nkf
    JIS X 0201 片仮名を JIS X 0208 片仮名に変換しないように、オプション -x を指定します。
    $ nkf-2.1.3/nkf -x --ic=Shift_JIS-2004 --oc=UTF-8 sjis-0213-2004-with-char.txt > sjis-0213-2004-nkf.txt

    iconv
    $ libiconv-1.14/src/iconv_no_i18n -f Shift_JIS-2004 -t UTF-8  sjis-0213-2004-with-char.txt > sjis-0213-2004-iconv.txt


    それぞれの出力ファイルを比較します。

    $ diff sjis-0213-2004-nkf.txt sjis-0213-2004-iconv.txt
    118c118
    < \     0x5C    U+00A5  # YEN SIGN
    ---
    > ¥     0x5C    U+00A5  # YEN SIGN
    152c152
    < ~     0x7E    U+203E  # OVERLINE
    ---
    > ‾     0x7E    U+203E  # OVERLINE
    298c298
    < ‾     0x8150  U+FFE3  # FULLWIDTH MACRON
    ---
    >  ̄    0x8150  U+FFE3  # FULLWIDTH MACRON
    360c360
    < ¥     0x818F  U+FFE5  # FULLWIDTH YEN SIGN
    ---
    > ¥    0x818F  U+FFE5  # FULLWIDTH YEN SIGN

    Shift_JIS-2004の変換では、4つの文字で異なる変換結果が得られました。

    • 円記号 (0x5C)
      • nkf   U+005C
      • iconv   U+00A5
    • オーバーライン (0x7E)
      • nkf   U+007E
      • iconv   U+203E
    • 全角マクロン (0x8150)
      • nkf   U+203E
      • iconv   U+FFE3
    • 全角円記号 (0x818F)
      • nkf   U+00A5
      • iconv   U+FFE5


    nkfでは、0x5Cと0x7Eは文字の意味に沿って変換するのではなく、ASCII互換として扱うようです。
    で、足りなくなった分を全角マクロンと全角円記号で補っている感じでしょうか。
    この辺りはオプションなどで色々変えられるのかもしれませんが、そこまでは調べませんでした。

    今回の使用・作成したファイルをGitHubに上げていますので、興味のある方はご覧ください。
    https://github.com/nathancorvussolis/difference-between-nkf-and-iconv

    2015年5月2日

    IMEの拡張機能


    IMEの各種設定のうちキーバインドやローマ字仮名変換ルールなどは基本的な機能として用意されていることがほとんどですが、例えば、標準以外の辞書を使いたいとか候補を整形したいなどの要望に答えるため、いくつかのIMEでは簡易的なスクリプトを組むことでそれらを実現できる機能を持っています。

    実現可能な機能については各IMEによって異なりますが、主に以下のような機能を有しているようです。
    1. 外部からデータを取得する
    2. 外部にデータを出力する
    3. 動的に候補や注釈を生成する
    4. これらをスクリプト言語で組める
    以下、拡張機能を持っているWindows用IMEの紹介です。


    ATOK


    ATOKダイレクトAPI
    http://atok.com/useful/developer/api/

    使用言語 : Perl, Ruby, Python


    SKK日本語入力FEP


    SKKGate
    http://coexe.web.fc2.com/skkgate.html
    SKKプラス
    http://coexe.web.fc2.com/skkextend.html

    使用言語 : JavaScript など


    CorvusSKK


    Lua拡張
    https://github.com/nathancorvussolis/corvusskk/wiki#Lua
    https://github.com/nathancorvussolis/corvusskk/blob/master/installer/config-lua/init.lua

    使用言語 : Lua


    SKK日本語入力FEPとCorvusSKKに関しては、操作体系の元ネタであるSKKがEmacsLispで記述された候補を実行して動的に候補を生成する機能を元々持っているので、これを拡張可能にしているのも自然な流れかなと思います。

    Windows用IMEでユーザー数が多いMS-IMEとGoogle日本語入力には拡張機能はないようですが、Android用のGoogle日本語入力やATOKには他のアプリのと連携を行うマッシュルーム機能があるそうです。

    以前某IMEでも話題になりましたが、気を付けなければならないのがIMEのセキュリティについてです。
    拡張機能を不用意に使うと穴ができる可能性があるので、製作者側にも使用者側にも慎重さが求められます。

    IME as a Possible Keylogger (symantec)
    https://www.symantec.com/avcenter/reference/ime.as.a.possible.keylogger.pdf

    それでは、良い連休を。