しってても教えてくれない。文字コードの呪い【前編】— ¥ と Shift_JIS が残した負債

パソコン

導入:なぜ“¥の呪い”は消えないのか

日本語のWordPressで数式やコードを書くと、「\¥ に見える」「メールやCSVで文字化けする」…そんな経験はありませんか?
原因は単純な“設定ミス”ではなく、1970〜90年代の歴史と互換性に根があります。本稿では、0x5C(バックスラッシュ)≒¥問題Shift_JIS(2バイト衝突)を軸に、実害と対処法を“日本語実運用”の視点でまとめます。


症状のカタログ(再現できるものだけ列挙)

  • C:\Windows\System32C:¥Windows¥System32 に見える(見た目だけ円)
  • KaTeX の \( … \) が機能せず、式が丸ごと無視される
  • JS/Python でパスリテラル "\n"改行として誤解釈(\t も同様)
  • Shift_JIS のメールやCSVが UTF-8 環境で 「□」「?」 に化ける

原因1:0x5C=「\」が、なぜ日本語では「¥」の見た目になる?

  • **ASCII(英語)**の 0x5C はバックスラッシュ \
  • JIS X 0201(旧JISローマ字・1969)0x5C に円マーク「¥」を割り当て
  • 以後、日本語フォントの多くは U+005C を「¥」の字形で描画
    同じコードでもフォントで 見た目が変わる というねじれが発生

実害

  • Windows日本語フォント(MSゴシック/游ゴシック等)は \¥グリフで描画
  • WebやWordPressで和文フォントを継承 → “\”が“¥”に見える
  • KaTeXで \to矢印コマンドに解釈され、意図が崩れる

原因2:Shift_JIS の“2バイト衝突”という構造的欠陥

  • 日本語を1バイトASCIIと共存させるため、**「英語は1バイト、日本語は2バイト」**の可変長案を採用
  • ところが 2バイト目ASCII領域(0x00–0x7F)と重なる値を含めてしまった
  • 文字列を1バイト単位で走査・切断・エスケープすると 途中で破壊される

代表的な事故

  • 2バイト目が 0x5C(バックスラッシュ)に当たる → エスケープと衝突
  • 2バイト目が 0x7E(~)などに当たる → 制御・装飾と衝突
  • CSV/メール/HTTPヘッダなど、ASCII前提の世界と噛み合わない

要するに:ASCIIの“空き”を再利用してしまい、重複を起こしたのが根本原因。


参考:当時の国・地域の方針(ざっくり)

地域主流コード衝突リスクその後
日本JIS, Shift_JIS高い(可変長+ASCII重複)Windows日本語で長期生存
中国GB2312→GBK→GB18030中〜低(ASCIIは左に維持)UTF-8移行が比較的スムーズ
韓国KS X 1001 / EUC-KR低(規則的な構造)UTF-8へ順調移行
台湾Big5中(実装差はあるが単純)ほぼUTF-8化

ここまでの実務メモ(WordPress/KaTeX)

1) 「\」を“必ずバックスラッシュ”で見せる

<style>
/* この投稿だけで等幅ラテン系に強制(おすすめ) */
.bs-scope, .bs-scope code, .bs-scope kbd { font-family: "Consolas","Menlo","Monaco","Courier New","Roboto Mono","Noto Sans Mono","DejaVu Sans Mono",monospace; font-variant-east-asian: normal;
}
</style> <div class="bs-scope"> <p>見た目:<code>&#92;</code> ← これで「\」固定表示</p>
</div>
  • 和文フォントだと U+005C が ¥グリフで描画されるため、英字等幅に切替が安全
  • 表ブロック内の <kbd> にも同様の指定を(投稿内限定でOK)

2) KaTeXで「\」を“記号として”出したい

<!-- MUプラグインの data-katex 直描画機構が有効な前提 -->
<span data-katex="\texttt{\text{\textbackslash}}"></span>
  • \text{\textbackslash} で **コマンドでない「\」**を出力
  • 属性内の \ が壊れる環境では &bsol;(= &#92;)を使う

3) “矢印の \to” を文字列で見せたい

<span data-katex="\texttt{\text{\textbackslash}to}"></span>

つまずきポイントと回避策(チェックリスト)

  • 見えるのが¥:フォントが和文を継承 → 英字等幅に切替(投稿内CSSで十分)
  • &#92; がそのまま出る:Gutenbergの「コード」ブロックはエスケープ表示仕様 → 段落/カスタムHTMLで <code>…</code> を使う
  • KaTeXが動かない\( … \) が壊れる環境 → data-katex="…" の直描画+ &bsol; 安全記法
  • WP Multibyte Patch が触る:保存時の整形でねじれ → 投稿側でエンティティ化(&#92;フォント切替が最短

コラム:PC-98 と DOS/V が“見た目互換”を崩した日

  • PC-98ROMフォントで「コード→字形」を固定(ハードが呪いを吸収)
  • DOS/Vデータフォント(TTF等)に移行 → フォント差で見た目崩壊
  • Windows 以降、MSゴシック/明朝/游ゴなどが U+005Cを¥で描画し続け、呪いが現在へ

まとめ(前編の結論)

  • ¥問題はフォント文化(JIS 0201の上書き)と互換性の結果
  • Shift_JISASCII重複の可変長で、壊れ方が構造的
  • 現代の安全地帯は UTF-8英字等幅フォントエスケープ徹底
  • 日本語WordPressでは、投稿単位CSS+&#92;+KaTeXの \text{\textbackslash} が最短ゴール

後編では 「フォントの呪い」—PC-98のROM文化からDOS/V・TrueType・“見た目が違う同じ文字”問題、波ダッシュ/全角チルダ/長音符の混乱までを、画像付き実例で掘ります。


付録:コピペ用スニペット集

A) 投稿内だけで「\」固定表示(最小)

<style>
.bs-scope, .bs-scope code, .bs-scope kbd { font-family: "Consolas","Menlo","Monaco","Courier New","Roboto Mono","Noto Sans Mono","DejaVu Sans Mono",monospace; font-variant-east-asian: normal;
}
</style>
<div class="bs-scope"><code>&#92;</code></div>

B) KaTeXで“文字としての \”

<span data-katex="\texttt{\text{\textbackslash}}"></span>

C) KaTeXで \( \) を文字で見せる

<span data-katex="\texttt{\text{\textbackslash}( ... \text{\textbackslash})}"></span>

D) テーブル内 <kbd> も“\”固定(投稿内)

<style>
.bs-scope .wp-block-table kbd { font-family: "Consolas","Menlo","Monaco","Courier New","Roboto Mono","Noto Sans Mono","DejaVu Sans Mono",monospace !important; font-variant-east-asian: normal !important;
}
</style>

免責メモ

  • 本記事は歴史的経緯の技術的検証を目的とし、いずれの規格団体/企業を誹謗するものではありません。
  • 語感の強い用語(「呪い」「黒歴史」等)は便宜上の比喩であり、当時の技術的制約・互換性要件に最大限敬意を払います。