ISO-2022-JP

概要

ISO-2022-JPはISO-2022の限定版です。ISO-2022-JPは21hから7Ehに対応する文字を下記のエスケープシーケンスで切り替えます。ISO-2022-JPでは行頭では21hから7EhにはASCIIが指示されています。JIS X 0208では21hから7Eh以外のコードは使われませず、コントロールコードやスペースはASCIIまたはJIS X 0201ローマ字であらわします。また行末ではASCIIまたはJIS X 0201ローマ字に戻します。通常はASCIIとJIS X 0208の1983年版が使われます。JIS X 0201カタカナは使えません。すべてのバイトは00hから7Fhまでが使われ、最上位ビットが立つことはありません。

エスケープシーケンス
1Bh 24h 42hJIS X 0208 (1983年版)
1Bh 24h 40hJIS X 0208 (1978年版)
1Bh 28h 42hASCII
1Bh 28h 4AhJIS X 0201 ローマ字

実装

SHIFT_JISへ変換

1行単位でSHIFT_JISへ変換をします。行頭では前の行に関係なく21hから7EhにはACSIIが指示されているものとします。

通常は1バイトをそのまま1文字にします。1Bh 24h 42hまたは1Bh 24h 40hがあらわれたときには漢字モードへ移行します。漢字モードでは2バイトを1組として下記の演算で変換し、2バイトで1文字とします。1Bh 28h 42hまたは1Bh 28h 4Ahがあらわれたときには漢字モードを解除し、1バイトをそのまま1文字にします。


(a1は最初の1バイト、a2は次の1バイト)
a2 += (a1 & 1) == 0 ? 0x7d : 0x1f;
if (a2 >= 0x7f)
  a2++;
a1 = (a1 - 0x21 >> 1) + 0x81;
if (a1>0x9f)
  a1 += 0x40;

SHIFT_JISから変換

1行単位でISO-2022-JPへ変換をします。行頭では漢字モードではないものとします。

81hから9FhまたはE0hからFCh以外の1バイトがあれたときにはその1バイトを1文字とします。このとき漢字モードのときには1Bh 28h 42hの3バイトをおき、漢字モードを解除します。

81hから9FhまたはE0hからFChの1バイトがあれたときには次の1バイトと組み合わせて下記の演算で変換し、2バイトで1文字になります。このとき漢字モードではないときにはその2バイトの前に1Bh 24h 42hの3バイトをおき、漢字モードへ変換します。

行末で漢字モードになっているときには1Bh 28h 42hの3バイトをおき、漢字モードを解除します。


(a1は最初の1バイト、a2は次の1バイト)
a1 -= a1 >= 0xe0 ? 0xc1 : 0x81;
a1 <<= 1;
if (a2 >= 0x9f)
  {
    a1 += 0x22;
    a2 -= 0x7e;
  }
else
  {
    a1 += 0x21;
    a2 -= a2 >= 0x80 ? 0x20 : 0x1f;
  }

判別

ファイルを先頭から解析して、下記の条件をすべて満たすときにはISO-2022-JPと判定します。1Bh 24h 42hまたは1Bh 24h 40hで漢字モードとなり、1Bh 28h 42hまたは1Bh 28h 4Ahで漢字モードを解除します。ファイルの先頭では漢字モードではありません。


戻る