Javaの日本語関連コンバータにおけるマッピングの違い

このドキュメントでは,「日本語のUnicodeベンダ依存文字表」の問題に関して,さらに新しいデータに基づいて分析しています.

特に注目すべきなのは,一般に"Shift-JIS"と呼ぶ漢字コードのバリエーションを処理するコンバータ (ByteToCharConverter & ByteToCharConverter)は,SJIS, MS932, CP943, CP943C, MacTECなど,複数存在することです.

しかし,これらの間には完全な互換性がないために,混在して使用すると問題が起こることがあります. そこで,どのような違いがあるかについて説明します.


byte -> char変換時

Unicodeの異なるコードポイントにマッピングされる日本語の文字を,以下の表にまとめてみました. データの抽出には,Java 2 SDK 1.3とMRJ 2.2.3 (MacTECのみ)を用いています.

コンバータのUnicodeマッピング表
JISの文字 Shift-JIS
コード位置
SJIS EUC_JP ISO2022JP MS932 CP943 CP943C MacTEC 1
ISO/IEC 646
\ (D/12, REVERSE SOLIDUS) 0x5C - - U+005C - - - -
~ (F/14, TILDE) 0x7E - - U+007E - - - -
JIS X 0201
\ (D/12, YEN SIGN) 0x5C U+005C U+005C U+00A5 U+005C U+00A5 U+005C U+00A5
~ (F/14, OVERLINE) 0x7E U+007E U+007E U+203E U+007E U+203E U+007E U+007E
JIS X 0208
 ̄ (1-17, OVERLINE) 0x8150 U+FFE3 U+FFE3 U+FFE3 U+FFE3 U+FFE3 U+FFE3 U+FFE3 2
― (1-29, EM DASH) 0x815C U+2015 U+2015 U+2015 U+2015 U+2014 U+2014 U+2014
〜 (1-33, WAVE DASH) 0x8160 U+301C U+301C U+301C U+FF5E U+301C U+301C U+301C
‖ (1-34, DOUBLE VERTICAL LINE) 0x8161 U+2016 U+2016 U+2016 U+2225 U+2016 U+2016 U+2016
… (1-36, HORIZONTAL ELLIPSIS) 0x8163 U+2026 U+2026 U+2026 U+2026 U+2026 U+2026 U+22EF 2
− (1-61, MINUS SIGN) 0x817C U+2212 U+2212 U+2212 U+FF0D U+2212 U+2212 U+2212
¢ (1-81, CENT SIGN) 0x8191 U+00A2 U+00A2 U+00A2 U+FFE0 U+FFE0 U+FFE0 U+00A2
£ (1-82, POUND SIGN) 0x8192 U+00A3 U+00A3 U+00A3 U+FFE1 U+FFE1 U+FFE1 U+00A3
¬ (2-44, NOT SIGN) 0x81CA U+00AC U+00AC U+00AC U+FFE2 U+FFE2 U+FFE2 U+00AC
その他
メーカ定義外字 - - - - -
ユーザ定義外字 - - - - -
JIS X 0212サポート - - - - - - -

  1. MacTECは,MRJでしか使用できないコンバータ名で,MacOSのText Encoding Converter機能拡張を呼び出します.
  2. 最近のMacTECでは,以前他の環境とは異なるコードポイントにマッピングしていたOVERLINE (U+203E -> U+FFE3)とHORIZONTAL ELLIPSIS (U+22EF -> U+2026)を,他と互換性を保つように修正されました.
  3. ユーザ定義外字は,Unicodeの私用領域 (Private Use Area)にマップされます. ただし,この領域の大きさは,コンバータによって以下の表のように異なります.
    外字領域表
    コンバータ Shift-JISの範囲 Unicodeの範囲
    MS932 0xF040〜0xF9FC U+E000〜U+E757
    CP943 0xF040〜0xF9FC U+E000〜U+E757
    CP943C 0xF040〜0xF9FC U+E000〜U+E757
    MacTEC 0xF040〜0xFCFC U+E000〜U+E98B

これから,以下のことがわかります.

  1. 現在使用されていないJIS X 0213の文字を使わなければ,SJIS,EUC_JP,ISO2022JPらのコンバータの間には,互換性があると言える.
  2. それ以外を除くと異なる文字にマッピングされるので,異なる系列のコンバータを入力と出力に使用することは,一般に文字列の比較に問題が出てくるだけでなく,出力時の文字化けの原因になる.


char -> byte変換時

マッピングが異なる上記の文字のCharToByteConverterにおけるサポート状況を,以下の表にまとめてみました. "○"がサポートされている場合で,"×"がサポートされていない場合です. サポートされていない場合には,一般には"?"などの未定義文字に変換されることが多いようですが,例外を発生することもあります.

コンバータのサポートしている文字
Unicodeの文字 Unicode
コード位置
SJIS EUC_JP ISO2022JP MS932 CP943 CP943C MacTEC
\ (REVERSE SOLIDUS) U+005C ×
~ (TILDE) U+007E ×
¢ (CENT SIGN) U+00A2 × ×
£ (POUND SIGN) U+00A3 × ×
¬ (NOT SIGN) U+00AC × ×
\ (YEN SIGN) U+00A5
~ (OVERLINE) U+203E
― (EM DASH) U+2014 × × × ×
― (HORIZONTAL BAR) U+2015 × ×
‖ (DOUBLE VERTICAL LINE) U+2016 ×
… (HORIZONTAL ELLIPSIS) U+2026
− (MINUS SIGN) U+2212 ×
‖ (PARALLEL TO) U+2225 × × × × ×
〜 (WAVE DASH) U+301C ×
… (MIDLINE HORIZONTAL ELLIPSIS) U+22EF × × × × × ×
− (FULLWIDTH HYPHEN-MINUS) U+FF0D × × × × ×
〜 (FULLWIDTH TILDE) U+FF5E × × × × ×
¢ (FULLWIDTH CENT SIGN) U+FFE0 × × ×
£ (FULLWIDTH POUND SIGN) U+FFE1 × × ×
¬ (FULLWIDTH NOT SIGN) U+FFE2 × × ×
 ̄ (FULLWIDTH MACRON) U+FFE3

この表から,MacTECを除くと,基本的に互換性がないということがわかるでしょう. MacTECでは,出力時にこれらの非互換性を吸収するように配慮されています. しかし,異なるコンバータを用いて変換したUnicode文字列がバイナリ比較で等しくならない問題がありますし,ServletやJSPなどを用いて他のプラットフォームに送信する場合には,必ずしも正しく見ることができないことに注意してください.


参考資料

  1. The Unicode Consortium: The Unicode Standard, Version 2.0, Addison Wesley, 1996.
  2. 日本工業標準調査会: 国際符合化文字集合(UCS) - 第一部 体系及び基本多言語面 JIS X 0221-1995 (ISO/IEC 10646-1:1993)
  3. TOG/JVC CDE/Motif技術検討WG: Unicodeとユーザ定義文字・ベンダ定義文字に関する問題点と解決策

風間 一洋 (NTT未来ねっと研究所)