Skip to content

MS_JIS2004

nishi_74322014 edited this page Sep 1, 2026 · 1 revision

JIS2004関連

概要

JIS2004(JIS X 0213:2004)

  • JIS2004 は JIS X 0208:1997(いわゆる JIS97)を拡張し、
    JIS 第三水準文字・JIS 第四水準文字を含む 4344 文字を追加した文字コード。
  • Windows Vista / Windows Server 2008(以下、Vista/2008 と略す)でサポートされた。

補足(本ページの読み方): 本ページは Windows Vista 移行期
(2007~2009 年頃)の調査記録
であり、
「Vista で字が変わった / 入力できる文字が増えた」ことへの対応が主題である。

【当時の状況】
   XP/2003 …… JIS90 のフォント・IME(拡張文字は入らない)
   Vista/2008 … JIS2004 のフォント・IME(拡張文字が入る)★
     → 混在環境で、文字が化ける/字形が違う/入力できてしまう

【現在の状況】
   ・XP/2003/Vista/2008 はすべてサポート終了
   ・現行の Windows は【すべて JIS2004 対応】
   ・したがって「混在」の問題は消えた

しかし、本ページが挙げる問題点のうち
問題点 3(サロゲート ペア・結合文字が Length に影響する)と
問題点 4(字形が違う)は、現在も現役の問題
である。
原文自身が「JIS2004 導入に於ける特段新しい注意点は問題点3の一点だけ
と述べており、この見立ては正確だった。

現在は、より広い範囲で同じ問題が起きている

当時 現在
JIS2004 の 304 字がサロゲート ペア 絵文字・拡張漢字で日常的にサロゲート ペアが来る
結合文字は IME パッドで意図的に入れた場合 macOS/iOS 由来のデータが NFD で来る絵文字の ZWJ 結合
対象は日本語の漢字 あらゆる言語・記号

つまり、本ページの技術的な要点は、対象を広げて今も通用する

問題

JIS2004 の導入の問題には以下のものがあるが、現存するシステムの殆どは、
JIS2004 の導入前からキャラクタ セット、文字コードについて同様の問題を持っている。
(例えば、JIS X 0208 → JIS X 0212 時の補助漢字の追加、エンコーディングの問題など)。

  • このため、JIS2004 以降に、新たに JIS 漢字が追加された場合も
    同様の方法で対処することができると考える。
  • また、JIS2004 導入に於ける特段新しい注意点(観点)は朱書きにしてある。

※ エンコードしないで入出力する場合は、連携先で問題点1、2を解決すれば良い。
JIS2004 導入に於ける特段新しい注意点(観点)は問題点3の一点だけである。

移行メモ(朱書きについて): 原文は「特段新しい注意点は朱書きにしてある」
と述べているが、移行元のページに朱書き(赤文字)は残っていない
文脈から、問題点 3 がそれに当たると読める
(直後に「特段新しい注意点は問題点3の一点だけ」とあるため)。

拡張文字セットの追加

JIS2004 拡張文字のセットが 907 文字(うち 304 文字がサロゲート ペア文字)、追加された。
Vista/2008 以外の現行 OS は JIS2004 の拡張文字セットに未対応
(拡張文字セットは、現状、Vista/2008 の機種依存文字となっている)。

  • 問題点1:フォントが無い場合、JIS2004 拡張文字が表示されない。
  • 問題点2:マシンの IMEが未対応の場合、JIS2004 拡張文字を入力できない。
  • 問題点3:サロゲート ペア文字・結合文字は、Length チェックなどに影響を与える。

[参考]:マイクロソフト サポート オンライン > Windows Vista で拡張された文字について
http://support.microsoft.com/kb/927488/ja

補足(現在の問題点 1・2 の状況): 問題点 1・2 は解消した

現在
フォント 現行 Windows の MS ゴシック / 明朝 / 游ゴシック / Meiryo は JIS2004 対応
IME 現行の Microsoft IME は既定で拡張文字を入力できる

ただし、フォントの問題は形を変えて残っている

・Linux コンテナには日本語フォントが入っていない
   → サーバ側で PDF/画像を作ると豆腐(□)になる
     ([帳票出力] 参照)
・拡張漢字(CJK 拡張 B 以降)は、対応フォントが限られる
   → 游明朝/游ゴシックでも欠けている字がある
   → Windows の「BIZ UD」「MS 明朝」でも全部は入っていない
・Web フォントを使う場合、サブセット化で落ちる

問題点 3 は解消していない。以降で詳しく扱う。

標準フォント デザインの変更

字形変更文字(標準フォントデザインが変更)が 168 字。

  • 問題点4:マシンによっては、字形変更文字の表示や印刷が異なる。

補足(168 字の字形変更は現在も残る問題): これは
**「同じコードのまま、字の形だけが変わった」**という変更である。

【例】
   U+9DD7「鴎」→「鷗」    ※ コードは同じ。フォントの描き方が変わった
   U+845B「葛」            ※ 下部が「匂」→「匃」
   U+8FBB「辻」            ※ しんにょうの点が 1 つ → 2 つ

 → データは 1 ビットも変わらない
 → 表示・印刷だけが変わる

なぜ厄介か:

・データ上は「同じ文字」なので、システムでは検出できない
・人名・地名では【字形が本人の認識と違う】ことが問題になる
・画面と帳票で違うフォントを使うと、【画面と紙で字が違う】
・過去に印刷した帳票と、今日の帳票で字が違う

現在の対処:

手段 内容
フォントを固定する 全端末・全プリンタで同じフォントを指定する(最も確実)
IVS を使う 異体字セレクタで字形を明示JIS文字・漢字コード
JIS90 互換フォント 現在は提供されていない(後述)
外字 最後の手段(Windowsの外字

IVS が本来の解である。

葛 (U+845B)              … フォント任せ(JIS2004 字形になる)
葛 (U+845B U+E0100)      … 【明示的に旧字形を指定】

ただし、IVS 対応フォントと、IVS を扱えるアプリケーションが要る
DB では2 文字分(4 バイト)を消費する点にも注意する。

エンコーディングの問題

エンコーディング処理に問題がある可能性がある。

  • 問題点5:他の環境へ(Unicode からそれ以外の文字コードに)エンコード出力できない可能性。
  • 問題点6:他の環境から(Unicode からそれ以外の文字コードに)エンコード入力できない可能性。

移行メモ(問題点 6 の括弧書きが問題点 5 と同じ): 問題点 6 は
**「それ以外の文字コードから Unicode に」**が正しいと読める
(「入力」であるため)。原文の括弧内が問題点 5 と同文になっている。

補足: この 2 つは、文字のチェック方式
「可逆チェック」で検出できる
問題である。

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var cp932 = Encoding.GetEncoding(932);

// 問題点5: 送れるか?
bool canSend = cp932.GetString(cp932.GetBytes(s)) == s;

"𠮟る".Length;                 // 3(サロゲート ペア + 1)
canSend                        // false ← CP932 に 𠮟 がない

連携先が CP932 しか受けられない場合の設計:

① 入力時に検査して弾く(利用者にその場で伝える)
② 保存はするが、連携時に代替文字へ置換する(要業務合意)
③ 連携先を UTF-8 対応にしてもらう ★ 本筋

② の「代替文字への置換」は業務判断が要る
「𠮟」→「叱」のような置換は、別の字にすることであり、
氏名では許されない場合が多い。

対応方法

JIS2004に対応させる

  • 以下は、Windows OS での対応方法。
  • Mac、UNIX、Linux、その他携帯端末などの他機種についても同様に調査が必要。
  • ただし、文字の表示が不要なサーバ OS については調査不要
    (エンコーディングの問題が起きない場合)。

JIS2004 対応の日本語フォントのインストール

Windows XP / Windows Server 2003(以下、XP/2003 と略す)でも、
パッチさえ当てれば、JIS2004 に対応した日本語フォントを利用可能になる。

  • Windowsホーム > 製品情報 > Windows Vista
    JIS X 0213 : 2004 対応と新日本語フォント「メイリオ」について
    XP / 2003向けJIS2004対応 MSゴシック & MS明朝 フォントパッケージについて
    (リンク切れ:http://www.microsoft.com/japan/windows/products/windowsvista/jp_font/jis04/default.mspx

  • マイクロソフト > ダウンロード センター > XP向けClearType対応日本語フォント
    (リンク切れ:ダウンロード センターの当該ページは提供終了)

フォントをインストールしたら、フォントを使用できるアプリケーションで確認する。
(フォントを使用のに設定が必要なアプリケーションもあるし、
フォントを使用できないアプリケーションもある)

移行メモ(リンクは提供終了): 本節が案内する
XP/2003 向けの追加フォント パッケージは、現在提供されていない
(XP/2003 のサポートが終了しているため)。
URL も 404 になるため、上記ではリンクを外して記録のみ残した

現行の Windows では、追加インストールなしで JIS2004 に対応済みである。

JIS2004 対応の IMEのインストール

  • Office2007(に同梱される IME2007)をインストールすることで、
    XP/2003 でも JIS2004 の拡張文字セットの文字入力が可能になる。
    Office2007 はインターネットから、試用版(無料で 60 日試用可能)がダウンロードできる。

  • ちなみに、IME2007 のみをインストールした状態では、フォントがないため、
    IME が入力したデータを参照することができないと言う現象が発生する。
    この場合、前述の手順に従い、JIS2004 に対応した日本語フォントをインストールすることで、
    この問題を解決する。

補足(「入力はできるが見えない」現象): 原文が記録している
**「IME だけ入れるとデータが見えない」**という現象は、
フォントと文字コードが独立していることをよく示している。

【入力できる】 …… IME が拡張文字を変換候補に出せるか
【保存できる】 …… アプリと DB が Unicode を扱えるか
【表示できる】 …… フォントにその字のグリフがあるか
【印刷できる】 …… プリンタ/PDF にフォントが埋め込まれるか

  → この 4 つは【別々の条件】であり、どれか 1 つでも欠けると
     「文字化け」に見える

障害切り分けの際は、この 4 段階を分けて確認する
特に**「表示できないが、データは正しい」**ケースを
データの破損と誤診して、正しいデータを壊してしまう事故が多い。

JIS90の設定に戻す

  • Vista/2008 では、JIS2004 に対応した日本語フォントを搭載している。
    一部の文字(168 字)で標準フォント デザインが変更されるため、
    人名、地名など字形に敏感なシステムには影響が出る可能性がある
    (この影響とは、顧客要件に因るところが大きい)。

    • [参考]:Windowsホーム > 製品情報 > Windows Vista > JIS2004 対応と新日本語フォント「メイリオ」について
      (リンク切れ:提供終了)
    • [参考]:CyberLibrarian(図書館員のコンピュータ基礎講座参考資料)> 参考資料 > JIS2004制定時の変更点 > 印刷標準字体に変更したもの(168字)
      http://www.asahi-net.or.jp/~ax2s-kmtn/ref/jis2000-2004.html
  • これを問題と捉えるならば、Vista/2008 のフォント、IME を JIS90 に対応させる必要がある。
    また、このような問題は、画面上の表示だけでなく、帳票印刷(プリンタ)なども含む。

    • [参考]:マイクロソフト サポート オンライン > フォントなどの JIS2004 文字セットをサポートする
      ドキュメントを Vista/2008 で印刷すると、
      デバイス フォントを使用するようにプリンタが構成されていても
      ドキュメントが TrueType フォントで印刷されることがある。
      http://support.microsoft.com/kb/931478/ja

日本語フォントをJIS90 対応のフォントに変更

Vista/2008 で 2000/XP 互換フォントを利用する場合、
2000/XP と同じデザインの JIS90 互換 MS ゴシック・明朝フォントが
ダウンロード提供されているのでこれをインストールする。

[参考]:Windowsホーム > 製品情報 > Windows Vista
JIS X 0213:2004 対応と新日本語フォント「メイリオ」について
Vista / 2008向けJIS90互換MSゴシック・明朝フォントパッケージについて
(リンク切れ:提供終了)

Vista/2008 で JIS90 互換 MS ゴシック・明朝フォントをインストールする前、
インストールした後で、「鰯」などの文字のフォント デザインが以下のように変更される。

日本語フォントをJIS90 対応のフォントに変更

補足(JIS90 互換フォントは現在入手できない): この対処は
現在は取れない

・JIS90 互換 MS ゴシック・明朝パッケージは【提供終了】
   (Vista/2008 向けであり、対象 OS がサポート終了)
・現行 Windows で「JIS90 の字形に戻す」公式手段はない

現在、字形を制御したい場合の選択肢:

手段 内容
IVS を使う 異体字セレクタで字形を明示本筋の解
字形を持つフォントを指定する BIZ UD 明朝、游明朝、モリサワ等の商用フォント
外字フォントを作る 最後の手段。運用負荷が高い
画像で持つ 帳票の一部だけ画像化(限定的な用途)

「字形が違う」を問題とするかは業務判断であるという
原文の指摘(「顧客要件に因るところが大きい」)は今も本質的である。
技術的に完璧を目指すとコストが跳ね上がるため、
どこまで求めるかを先に合意する

Vista/2008の IMEをJIS90に設定

Vista/2008 の IME 設定を変更することで
JIS2004 の拡張文字セットの入力を禁止することができる。

Vista/2008 向け JIS90 互換 MS ゴシック・明朝フォントパッケージのインストール後、
日本語入力 IME での変換対象を「JIS90」に限定する設定をすることで、
拡張文字セット入力を不可能にすることができる。

言語バーにある、プロパティから、[Microsoft IME のプロパティ]ダイアログを起動、
[変換]タブの[変換文字制限]ボタンを押下し、
[Microsoft IME 変換文字制限]ダイアログで
[JISX0208 文字で構成された単語/文字のみ変換候補に表示する]チェック ボタンをオンにして、
[OK]ボタンを2回押下して元に戻る。

日本語フォントをJIS90 対応のフォントに変更(Vista/2008)

上記の JIS2004 の拡張文字セット入力を不可能にする設定を”する前”と、”した後”の比較を以下に示す。
確かに、JIS2004 の拡張文字セットを入力できなくなっている。

JIS90に対応したIME設定に変更した結果(Vista/2008)

[参考]:マイクロソフト サポート オンライン > Vista/2008でIMEの変換候補に表示する文字を制限する方法
http://support.microsoft.com/kb/934715/ja

JIS90 対応の IMEのインストール

また、XP/2003 で Office2007(に同梱される IME2007)をインストールして、
JIS2004 の拡張文字セットの文字入力が可能にした場合も、
IME 設定を変更することで JIS2004 の拡張文字セットの入力を禁止することができる。

言語バーにある、プロパティから、[Microsoft Office IME 2007 のプロパティ]ダイアログを起動、
[変換]タブの[詳細設定]ボタンを押下し、
[変換]ダイアログで[JISX0208 文字で構成された単語/文字のみ変換候補に表示する]
オプション ボタンをオンにして、[OK]ボタンを2回押下して元に戻る。

日本語フォントをJIS90 対応のフォントに変更(XP/2003)

上記の JIS2004 の拡張文字セット入力を不可能にする設定をする前と、した後の比較を以下に示す。
確かに、JIS2004 の拡張文字セットを入力できなくなっている。

JIS90に対応したIME設定に変更した結果(XP/2003)

補足(IME での入力制限は現在も設定できるが、意味が薄れた): 現行の
Microsoft IME にも同等の設定はある。

設定 → 時刻と言語 → 言語と地域 → 日本語 → 言語のオプション
  → Microsoft IME → 全般 → 変換候補の文字セット制限
      ・制限しない
      ・JIS X 0208 のみ ★
      ・JIS X 0213 のみ

しかし、この対策の有効性は大きく下がっている

【IME 制限が効かない入力経路】
   ・コピー&ペースト(IME を経由しない)★
   ・Web フォーム(ブラウザ経由。IME 制限は効くが端末依存)
   ・スマートフォン(Windows の IME 設定と無関係)
   ・CSV/Excel 取り込み、API 連携、OCR
   ・端末ごとの設定なので、【全端末を管理できないと穴が残る】

**したがって、現在の正しい設計は
「入力を IME で止める」ではなく「アプリケーション側で検査する」**である。

// 入力チェック(サーバ側で必ず行う)
if (!IsRoundTrippable(input, 932))
    return Error("登録できない文字が含まれています…");

クライアント側の制限は補助であり、
サーバ側の検査が唯一の保証——
という、入力検証一般の原則がそのまま当てはまる。

サロゲート ペア文字、結合文字

  • UTF-8、UTF-16 で表現可能
  • Shift-JIS、EUC-JP、Big5 などでは表現できない

サロゲート ペア文字

追加された JIS2004 拡張文字のセット、907 文字のうち 304 文字がサロゲート ペア文字である。
サロゲート ペア文字のことを、サロゲートコード、補助文字とも呼ぶ。

サロゲート ペア文字は 4 バイトで表現される。

補足(「4 バイト」の意味): 文脈によって値が変わるため補足する。

表現 バイト数
UTF-16(.NET の string の内部) 4 バイトchar 2 個)← 原文はこれ
UTF-8 4 バイト(偶然一致する)
UTF-32 4 バイト
CP932 / EUC-JP 表現できない
𠮟 (U+20B9F)
   UTF-16: D8 42 DF 9F  (サロゲート ペア D842 + DF9F)
   UTF-8 : F0 A0 AE 9F

string.Length が 2 を返すのは UTF-16 の単位数を数えるためである
文字のチェック方式)。

U+2000B:𠀋 U+2123D:𡈽 U+2131B:𡌛 U+2146E:𡑮 U+218BD:𡢽 U+20B9F:𠮟 U+216B4:𡚴
U+21E34:𡸴 U+231C4:𣇄 U+235C4:𣗄 U+2373F:𣜿 U+23763:𣝣 U+23CFE:𣳾 U+247F1:𤟱
U+2548E:𥒎 U+2550E:𥔎 U+25771:𥝱 U+259C4:𥧄 U+25DA1:𥶡 U+26AFF:𦫿 U+26E40:𦹀
U+270F4:𧃴 U+27684:𧚄 U+28277:𨉷 U+283CD:𨏍 U+2A190:𪆐 U+20089:𠂉 U+200A2:𠂢
U+200A4:𠂤 U+201A2:𠆢 U+20213:𠈓 U+2032B:𠌫 U+20381:𠎁 U+20371:𠍱 U+203F9:𠏹
U+2044A:𠑊 U+20509:𠔉 U+205D6:𠗖 U+20628:𠘨 U+2074F:𠝏 U+20807:𠠇 U+2083A:𠠺
U+208B9:𠢹 U+2097C:𠥼 U+2099D:𠦝 U+20AD3:𠫓 U+20B1D:𠬝 U+20D45:𠵅 U+20DE1:𠷡
U+20E95:𠺕 :𠹭 U+20E64:𠹤 U+20F5F:𠽟 U+21201:𡈁 U+21255:𡉕 U+2127B:𡉻
U+21274:𡉴 U+212E4:𡋤 U+212D7:𡋗 U+212FD:𡋽 U+21336:𡌶 U+21344:𡍄 U+213C4:𡏄
U+2146D:𡑭 U+215D7:𡗗 U+26C29:𦰩 U+21647:𡙇 U+21706:𡜆 U+21742:𡝂 U+219C3:𡧃
U+21C56:𡱖 U+21D2D:𡴭 U+21D45:𡵅 U+21D78:𡵸 U+21D62:𡵢 U+21DA1:𡶡 U+21D9C:𡶜
U+21D92:𡶒 U+21DB7:𡶷 U+21DE0:𡷠 U+21E33:𡸳 U+21F1E:𡼞 U+21F76:𡽶 U+21FFA:𡿺
U+2217B:𢅻 U+2231E:𢌞 U+223AD:𢎭 U+226F3:𢛳 U+2285B:𢡛 U+228AB:𢢫 U+2298F:𢦏
U+22AB8:𢪸 U+22B4F:𢭏 U+22B50:𢭐 U+22B46:𢭆 U+22C1D:𢰝 U+22BA6:𢮦 U+22C24:𢰤
U+22DE1:𢷡 U+231C3:𣇃 U+231F5:𣇵 U+231B6:𣆶 U+23372:𣍲 U+233D3:𣏓 U+233D2:𣏒
U+233D0:𣏐 U+233E4:𣏤 U+233D5:𣏕 U+233DA:𣏚 U+233DF:𣏟 U+2344A:𣑊 U+23451:𣑑
U+2344B:𣑋 U+23465:𣑥 U+234E4:𣓤 U+2355A:𣕚 U+23594:𣖔 U+23639:𣘹 U+23647:𣙇
U+23638:𣘸 U+2363A:𣘺 U+2371C:𣜜 U+2370C:𣜌 U+23764:𣝤 U+237FF:𣟿 U+237E7:𣟧
U+23824:𣠤 U+2383D:𣠽 U+23A98:𣪘 U+23C7F:𣱿 U+23D00:𣴀 U+23D40:𣵀 U+23DFA:𣷺
U+23DF9:𣷹 U+23DD3:𣷓 U+23F7E:𣽾 U+24096:𤂖 U+24103:𤄃 U+241C6:𤇆 U+241FE:𤇾
U+243BC:𤎼 U+24629:𤘩 U+246A5:𤚥 U+24896:𤢖 U+24A4D:𤩍 U+24B56:𤭖 U+24B6F:𤭯
U+24C16:𤰖 U+24D14:𤴔 U+24E0E:𤸎 U+24E37:𤸷 U+24E6A:𤹪 U+24E8B:𤺋 U+2504A:𥁊
U+25055:𥁕 U+25122:𥄢 U+251A9:𥆩 U+251E5:𥇥 U+251CD:𥇍 U+2521E:𥈞 U+2524C:𥉌
U+2542E:𥐮 U+254D9:𥓙 U+255A7:𥖧 U+257A9:𥞩 U+257B4:𥞴 U+259D4:𥧔 U+25AE4:𥫤
U+25AE3:𥫣 U+25AF1:𥫱 U+25BB2:𥮲 U+25C4B:𥱋 U+25C64:𥱤 U+25E2E:𥸮 U+25E56:𥹖
U+25E65:𥹥 U+25E62:𥹢 U+25ED8:𥻘 U+25EC2:𥻂 U+25EE8:𥻨 U+25F23:𥼣 U+25F5C:𥽜
U+25FE0:𥿠 U+25FD4:𥿔 U+2600C:𦀌 U+25FFB:𥿻 U+26017:𦀗 U+26060:𦁠 U+260ED:𦃭
U+26270:𦉰 U+26286:𦊆 U+2634C:𦍌 U+23D0E:𣴎 U+26402:𦐂 U+2667E:𦙾 U+266B0:𦚰
U+2671D:𦜝 U+268DD:𦣝 U+268EA:𦣪 U+26951:𦥑 U+2696F:𦥯 U+269DD:𦧝 U+26A1E:𦨞
U+26A58:𦩘 U+26A8C:𦪌 U+26AB7:𦪷 U+26C73:𦱳 U+26CDD:𦳝 U+26E65:𦹥 U+26F94:𦾔
U+26FF8:𦿸 U+26FF6:𦿶 U+26FF7:𦿷 U+2710D:𧄍 U+27139:𧄹 U+273DB:𧏛 U+273DA:𧏚
U+273FE:𧏾 U+27410:𧐐 U+27449:𧑉 U+27615:𧘕 U+27614:𧘔 U+27631:𧘱 U+27693:𧚓
U+2770E:𧜎 U+27723:𧜣 U+27752:𧝒 U+27985:𧦅 U+27A84:𧪄 U+27BB3:𧮳 U+27BBE:𧮾
U+27BC7:𧯇 U+27CB8:𧲸 U+27DA0:𧶠 U+27E10:𧸐 U+27FB7:𧾷 U+2808A:𨂊 U+280BB:𨂻
U+28282:𨊂 U+282F3:𨋳 U+2840C:𨐌 U+28455:𨑕 U+2856B:𨕫 U+285C8:𨗈 U+285C9:𨗉
U+286D7:𨛗 U+286FA:𨛺 U+28949:𨥉 U+28946:𨥆 U+2896B:𨥫 U+28987:𨦇 U+28988:𨦈
U+289BA:𨦺 U+289BB:𨦻 U+28A1E:𨨞 U+28A29:𨨩 U+28A71:𨩱 U+28A43:𨩃 U+28A99:𨪙
U+28ACD:𨫍 U+28AE4:𨫤 U+28ADD:𨫝 U+28BC1:𨯁 U+28BEF:𨯯 U+28D10:𨴐 U+28D71:𨵱
U+28DFB:𨷻 U+28E1F:𨸟 U+28E36:𨸶 U+28E89:𨺉 U+28EEB:𨻫 U+28F32:𨼲 U+28FF8:𨿸
U+292A0:𩊠 U+292B1:𩊱 U+29490:𩒐 U+295CF:𩗏 U+2967F:𩙿 U+296F0:𩛰 U+29719:𩜙
U+29750:𩝐 U+298C6:𩣆 U+29A72:𩩲 U+29DDB:𩷛 U+29E3D:𩸽 U+29E15:𩸕 U+29E8A:𩺊
U+29E49:𩹉 U+29EC4:𩻄 U+29EE9:𩻩 U+29EDB:𩻛 U+29FCE:𩿎 U+2A02F:𪀯 U+2A01A:𪀚
U+2A0F9:𪃹 U+2A082:𪂂 U+22218:𢈘 U+2A38C:𪎌 U+2A437:𪐷 U+2A5F1:𪗱 U+2A602:𪘂
U+2A61A:𪘚 U+2A6B2:𪚲

移行メモ(表の字数は 303): 本文は「304 文字がサロゲート ペア文字」と述べているが、\n> 実際の表に含まれるのは 303 字である(重複なし)。\n> 移行元の表が 1 字欠けているものと思われる。\n> また、U+20E6D のセルはコロンが抜けていたため、他と揃えた。

結合文字

結合文字のことを、結合済み文字、合成文字、合成済み文字とも呼ぶ。

結合文字は 4 バイト以上で表現される。

結合文字は、言語バーにある、IME パッドから、「ふ」+「゚」=「ぷ」と入力することで、
入力できる。下記の図は、通常の文字の「ぷ」と、結合文字の「ぷ」を入力したところ。

結合文字の入力

また結合文字は、縦書きにすると、正しく結合されないという問題がある。

結合文字の縦書き

移行メモ(用語の整理): 原文は「結合文字」の別名として
結合済み文字、合成文字、合成済み文字」を挙げているが、
Unicode の用語では「結合」と「合成済み」は逆の概念であるため、
整理しておく。

用語 意味
結合文字(Combining Character) 単独では使わない付加記号。U+3099(濁点)、U+309A(半濁点)等
結合文字列(Combining Sequence) 基底文字 + 結合文字。「ふ」+「゚」の 2 文字
合成済み文字(Precomposed) 1 文字で表せるもの。「ぷ」U+3077
「ぷ」には 2 通りの表現がある
   ① U+3077          合成済み(1 char)★ 通常はこちら
   ② U+3075 U+309A   結合文字列(2 char)← 原文の実験で作ったもの

   → 見た目は同じ。バイト列は違う。比較すると【一致しない】

原文が「結合文字」と呼んでいるのは ② の結合文字列である。

対策は正規化である(文字のチェック方式)。

"ぷ".Normalize(NormalizationForm.FormC);   // ② → ① に統一される

「縦書きで結合されない」問題は、
フォントとレンダリング エンジンの実装依存であり、
現在も環境によっては再現する
(縦書きは Word、InDesign、CSS の writing-mode 等で扱いが異なる)。
合成済み文字に正規化しておけば起きないため、
ここでも正規化が有効である。

文字の扱いの違い

API や DBMS の使い方によって、

  • 1 文字として扱えるか
  • 2 バイト毎にバラバラに扱うか

動作が変わる。

以下に一例を示す。

.NET FrameworkのAPI

  • System.Globalization.StringInfo は、1文字と認識する。
  • System.String は、1文字と認識しない。

SQL Serverの照合順序

  • Japanese_90, Japanese_100 は、1文字と認識する。
  • Japanese は、1文字と認識しない。

Oracleの部分検索

  • LIKEC は、1文字と認識する。
  • LIKE は、1文字と認識しない。

補足(この節が本ページの核心): 原文が挙げるこの 3 つの対比は、
**「どの層でも同じ問題が起きる」**ことを示しており、
現在もそのまま通用する。現在の情報で更新する

① .NET

API サロゲート ペア 結合文字列
string.Length 2 と数える 2 と数える
foreach (char c in s) 分解される 分解される
Rune / EnumerateRunes() 1 と数える 2 と数える(別のコードポイント)
StringInfo.LengthInTextElements 1 と数える 1 と数える
Substring 壊れ得る 壊れ得る
SubstringByTextElements 安全 安全

RuneStringInfo の違いに注意する。
Runeコードポイント単位
StringInfo書記素クラスタ(見た目の 1 文字)単位である。

② SQL Server

照合順序 サロゲート ペア
Japanese_CI_AS 1 文字として扱わない
Japanese_90_CI_AS / Japanese_XJIS_100_CI_AS 扱う
*_SC(Supplementary Character 対応) 正しく扱う
*_UTF8(SQL Server 2019~) UTF-8 の varchar
-- 現在の推奨
ALTER DATABASE MyDb COLLATE Japanese_XJIS_140_CI_AS_SC;
--                                                 ↑ SC が肝

SELECT LEN(N'𠮟る');   -- SC なし: 3 / SC あり: 2

_SC が付いていないと、LEN / SUBSTRING / CHARINDEX
サロゲート ペアを 2 文字として数える

SQL Server)。

列の型も重要である。

varchar  … コードページ依存。【CP932 の範囲しか入らない】
nvarchar … UTF-16。【拡張文字が入る】★
varchar + UTF-8 照合順序(2019~)… UTF-8 で格納。ASCII 主体なら省容量

③ Oracle

LIKEC(C は Character)はコードポイント単位で比較する。
同様に LENGTHC / SUBSTRC / INSTRC がある。

SELECT LENGTH('𠮟る')  FROM dual;  -- 3(コード単位)
SELECT LENGTHC('𠮟る') FROM dual;  -- 2(コードポイント)

設計上の指針:

・DB の文字数制限は【何を数えているか】を確認する
    → VARCHAR2(10 CHAR) と VARCHAR2(10 BYTE) は別物
・画面の「10 文字まで」と DB の「10 文字」を一致させる
    → 画面は書記素、DB はコードポイントや UTF-16 単位
    → 【厳しい方に合わせる】か、明示的に換算する
・切り詰め(truncate)は【必ず文字単位の API を使う】
    → バイト単位・char 単位で切ると壊れた文字ができる

参考

Microsoft Learn


Tags: 移行, .NET開発, 国際化対応, 文字コード

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally