波ダッシュ問題の全貌: 〜 vs ~ と7つのマッピング不一致

7つの JIS-Unicode マッピング不一致の完全リファレンス。インタラクティブな切り替えで両方を確認。

なぜ同じバイトが2つのUnicode文字にマッピングされるのか

JIS X 0208 の1区33点は「波ダッシュ」— 日本語で範囲を示す波線記号(例: 3時〜5時)です。JIS を Unicode にマッピングする際、2つの組織が異なる選択をしました:

マッパーJIS 1-33 →文字名前
Unicode.org(JIS X 0208:1997 附属書)U+301CWAVE DASH
Microsoft(CP932 / Windows-31J)U+FF5EFULLWIDTH TILDE

見た目は似ていますが意味が異なります。U+301C WAVE DASH は JIS 波ダッシュの標準 Unicode マッピングです。U+FF5E FULLWIDTH TILDE は ASCII チルダ(~)の全角形であり、本来 JIS 波ダッシュを表すものではありません。

Microsoft が U+FF5E を選んだ理由は、初期の Windows 上で U+301C のグリフが上下反転した波形で表示されたためです。グリフを修正する代わりに、別のコードポイントにマッピングするという判断がなされました。

完全な一覧表: 7つの不一致

波ダッシュが最も有名ですが、Unicode.org/JIS 標準マッピングと Microsoft CP932 マッピングの間には実際に7つの不一致が存在します:

JIS 区点JIS 名称Unicode.orgMicrosoft CP932説明
1-17ダッシュU+2014 —U+2015 ―Em dash vs 水平バー
1-29マイナス記号U+2212 −U+FF0D -マイナス vs 全角ハイフンマイナス
1-33波ダッシュU+301C 〜U+FF5E ~波ダッシュ vs 全角チルダ
1-36双柱U+2016 ‖U+2225 ∥双柱 vs 平行
1-61セント記号U+00A2 ¢U+FFE0 ¢セント vs 全角セント
1-81ポンド記号U+00A3 £U+FFE1 £ポンド vs 全角ポンド
1-82否定記号U+00AC ¬U+FFE2 ¬否定 vs 全角否定

すべてのケースで、Microsoft は Unicode.org が正しい意味的マッピングとする文字ではなく、全角または視覚的に類似した変種を選択しています。

歴史的経緯: なぜこうなったのか

根本原因は1990年代初頭に遡ります:

  • 1993年: Microsoft が Windows 3.1J で CP932 を出荷。Unicode のグリフレンダリングが成熟する前にマッピングを作成。
  • 1997年: JIS X 0208:1997 の附属書に公式 Unicode マッピングが収録されたが、Microsoft のものと異なっていた。
  • 2000年代: 不一致が広く認識された頃には、両方のマッピングで作成された文書が膨大に存在。

どちらのマッピングも絶対的に「間違い」ではありません。Microsoft は自社プラットフォームでの見た目を優先し、JIS 標準は意味的な正確性を優先しました。

実用上の影響: どこで問題が起きるか

波ダッシュ問題は以下のような実際のシナリオで顕在化します:

  • データベース移行: Oracle(JIS/Unicode.org マッピングを使用することが多い)と SQL Server(Microsoft マッピングを使用)間のデータ変換で、文字がサイレントに入れ替わる可能性。
  • メール: JIS エンコードされたメールを異なるマッピングテーブルでデコードすると誤った文字が表示される。
  • Web フォーム: macOS(U+301C を使用)で入力した〜と、Windows(歴史的に U+FF5E を使用)で入力した~は、「同じ」文字なのに異なるデータになる。
  • 検索: 〜で検索しても~はヒットしない。ユーザーにとっては同一の文字なのに。
// 見た目は似ているが異なるコードポイント:
"〜".codePointAt(0).toString(16)  // "301c" (WAVE DASH)
"~".codePointAt(0).toString(16)  // "ff5e" (FULLWIDTH TILDE)

// 直接比較は失敗:
"〜" === "~"  // false

// NFKC 正規化でも解決しない:
"〜".normalize("NFKC") === "~".normalize("NFKC")  // false

どちらのマッピングを使うべきか

文脈によって推奨が異なります:

文脈推奨理由
新規データ / Unicode ネイティブUnicode.org (U+301C)JIS 標準に基づく正しい意味的マッピング
Windows 連携 / レガシーMicrosoft (U+FF5E)既存の CP932 データと一致
WHATWG Encoding StandardMicrosoft (U+FF5E)ブラウザは CP932 互換マッピングを使用
Apple プラットフォームUnicode.org (U+301C)macOS/iOS は JIS 標準マッピングを使用

WHATWG Encoding Standard(全ウェブブラウザが使用)は Shift_JIS デコード時に Microsoft マッピングに従います。つまりブラウザが Shift_JIS ページをデコードすると、JIS 1-33 は U+301C ではなく U+FF5E になります。これは実用的な選択です: Shift_JIS コンテンツの大半は Windows で作成されたためです。

このツールでは2つのマッピングテーブルを切り替えて、各バイト列がどう解釈されるかを確認できます。

より広いパターン: 日本語だけの問題ではない

波ダッシュ問題はマッピング不一致の最も有名な例ですが、他のエンコーディングにも類似の問題が存在します:

  • EUC-KR / CP949: 韓国語エンコーディングにも KS 標準と Microsoft 実装の間でマッピングの不一致がある。
  • Big5 / CP950: 繁体字中国語エンコーディングも公式標準と Microsoft 拡張の間で同様に乖離。
  • GB2312 / GBK / CP936: 簡体字中国語エンコーディングは複数の非互換な拡張を経て成長。

教訓は普遍的です: 文字エンコーディングが複数の当事者によって独立に Unicode にマッピングされた場合、不一致はほぼ不可避でした。Unicode 自体に非はなく、問題はレガシーから Unicode への変換が多対一であることに起因します。

関連記事