Shift JIS

**Shift_JIS**（シフトジス）は、コンピュータ上で日本語を含む文字列を表現するために用いられる文字コードの一つ。**シフトJIS**（シフトジス）と表記されることもある。

かつてはベンダーによる独自拡張を含む文字コード群を指した曖昧な名称であったが、1997年にJIS X 0208で標準化された。

## 構造
JIS X 0201を1バイトで、JIS X 0208を2バイトで符号化する可変幅文字符号化方式。2バイト文字は、第1バイトに-または-の47通り、第2バイトに-または-の188通りを用いる。

さらに、JIS X 0213に拡張したShift_JIS-2004では、第１バイトの領域である-を利用している。

## 歴史
### Shift_JISの誕生
1980年代、パソコン用16ビットCPUの普及もあいまって、漢字やひらがな・カタカナを表示可能なハードウェアを備えた情報機器が続々と発売された。これらの製品では、日本語を表現できる文字符号化方式が模索されており、先行してJIS C 6220（現在のJIS X 0201）の8ビット符号（以下「英数字・半角カナ」）と、JIS C 6226（現在のJIS X 0208、以下「漢字」）がよく利用されていた。この両文字集合の混在にあたっては、ISO 2022によるエスケープシーケンスで文字集合を切り替える設計となっていた。

Shift_JISの設計では、ファイルサイズ節約や処理時間短縮を図るため、これら文字集合をエスケープシーケンスなしで混在可能にすることを企図した。 ISO 2022では、英数字・半角カナ・漢字はそれぞれ、8ビット符号空間の中のGL(-)・GR(-)のいずれか1領域を使うことで表現する。このうち英数字・漢字だけの混在であれば英数字をGL、漢字をGRに割り当てることもできるが、既にGLに英数字、GRに半角カナを割り当てた実装が普及しており、既存のGL・GR領域に漢字を混在させることは困難だった。

1982年、漢字の符号位置をこれら符号空間の隙間に押し込む形でShift_JISが実装された。これを実現するためには、漢字の1バイト目として、ISO 2022において不使用のCR（-）領域に加え、半角カナに割り当てられていたGR領域に約3分の1残されていた未使用領域から捻出することとした。さらに2バイト目には、ISO 2022とは異なり、英数字・半角カナに使用済みの領域をも含む、GL、CR、GRにあたる各領域のほぼ全てを使う必要があった。ただし、GL領域においては、JIS X 0201の記号に当たる部分は極力避けた。

マイクロソフト日本法人元会長の古川享によると、Shift_JISの制定にはアスキー、マイクロソフト（米）、三菱電機、マイクロソフトウェア・アソシエイツ、デジタルリサーチ（米）が関わり、特にアスキーの山下良蔵が中心となって行われたという。これに対する異説として、京都大学助教授の安岡孝一は、マイクロソフトウェア・アソシエイツと三菱電機のみの共同開発だと主張していたが、山下本人の発言により安岡は自説を撤回する発言をしている。また古くは**'の訳書 (ISBN 4-7561-0783-4) の「UNIX人名事典」翻訳版加筆部分 (p.45) で、[[深瀬弘恭]]に「MS漢字コードの作者の一人」という紹介文が書かれていた。

=== 初期の実装 ===
Shift_JISはマイクロソフトの[[MS-DOS]]に「MS漢字コード」（および後の[[Microsoftコードページ932]]）、デジタルリサーチの[[CP/M-86]]に「SJC-26」として採用された。両者はほぼ同じだが、[[全角スペース]]の扱いに違いがある。全角スペースにMS-DOSはを割り当てているが、CP/M-86は半角スペース2文字分と同等のを割り当てている。CP/M-86での実装は文字列からスペースを探索する処理が簡単になるという[[プログラミング]]上の利点があった。一方、MS-DOSは全角スペースに別のコードを割り当てることで、半角入力モードで[[スペースキー]]が2回押されたのか、全角入力モードでスペースキーが1回だけ押されたのかをプログラムが判別できるようにした。これは当時のアプリケーションソフト（[[Microsoft Multiplan|Multiplan]]など）でメニュー選択にスペースキーを使用していたためであった。また、[[プリンター]]では全角スペースと半角スペースの幅の比が2対1でない場合があるため、スペースの区別は[[帳票]]設計に影響があった。

=== 標準化 ===
Shift_JISは ISO 2022の符号化の範囲外にあるベンダー独自の実装として誕生しており、普及後もしばらく標準化されずにいたが、JIS X 0208:1997において附属書1で「シフト符号化表現」という名前で仕様が定義された。また、[[Internet Assigned Numbers Authority|IANA]]においても「Shift_JIS」の名称が登録されている。

JIS X 0208の拡張規格であるJIS X 0213では、[[2000年]]制定時に附属書1で上位互換仕様の**Shift_JISX0213**が定められ、[[2004年]]改定時に**Shift_JIS-2004**と名称が変更された。

その後は更新は停止したが、日本語版Windowsが長らく標準をShift_JISに定めていたことで使用され続けた。不都合が多いため[[Unicode]]への移行が呼びかけられている。

== 符号化方式 ==
=== 区点番号の割当 ===
[[JIS X 0208]]では文字集合が[[区点番号]]として94×94の文字表の行と列の番号の組で表現される。これら区点番号をShift_JISでは以下のような対応で符号化している。



[[JIS X 0213]]では94×94の文字表が2つあり、それぞれ第1面・第2面と表現される。第1面(第1・2・3水準)は上記符号化の範囲に収まる。第2面(第4水準)は区番号が1・3・4・5・8・12-15・78-94区と不連続に構成されており、この26区分を収録するためにShift_JIS-2004では以下のように対応している。


=== 区点番号からの変換 ===
面区点番号 <math>m, k, t</math> から Shift_JISの 第1バイト<math>s_1</math>・第2バイト<math>s_2</math>は以下の式で求められる。<math>\lfloor x \rfloor</math>は[[床関数]]。

:<math>s_1 = \begin{cases} \left \lfloor \frac{k + 257}{2} \right \rfloor & \mbox{if } m = 1 \mbox{ and } 1 \le k \le 62 \\
                           \left \lfloor \frac{k + 385}{2} \right \rfloor & \mbox{if } m = 1 \mbox{ and } 63 \le k \le 94 \\
                           \left \lfloor \frac{k + 479}{2} \right \rfloor - \left \lfloor \frac{k}{8} \right \rfloor \times 3 & \mbox{if } m = 2 \mbox{ and } k = 1, 3, 4, 5, 8, 12, 13, 14, 15 \\
                           \left \lfloor \frac{k + 411}{2} \right \rfloor & \mbox{if } m = 2 \mbox{ and } 78 \le k \le 94             \end{cases}</math>
:<math>s_2 = \begin{cases} t + 63 & \mbox{if } k \mbox{ is odd and } 1 \le t \le 63 \\
                           t + 64 & \mbox{if } k \mbox{ is odd and } 64 \le t \le 94 \\
                           t + 158 & \mbox{if } k \mbox{ is even }
             \end{cases}</math>

=== 符号化可能な文字数 ===
初期のShift_JISでは、第1バイトが47通り、第2バイトが188通りの符号があるため、 47 × 188 = 94 × 94 = 8836 の2バイト文字を表現することができ、これはJIS X 0208で規定された区点番号のすべてを収められるように設計されている。ここに158字の英数字・半角カナ（スペース含む、DEL除く）を加えると、計 8994 文字となる。

さらに、第1バイトは-を用いることで60通りまで拡張されており、 60 × 188 + 158 = 11438 文字を表現することができる。[[Microsoftコードページ932]]の[[IBM拡張文字]]やShift_JIS-2004の第4水準文字の符号化ではこれらの領域を動員している。

== 特徴 ==
; 利点
:# 全角文字と、JIS X 0201で定義したいわゆる半角カナ文字を同一のコード体系で表現できる。
:# 日本語環境においては、MS-DOSで日本語用文字コードとして採用されて以来、パソコンにおいて圧倒的な普及度があり、その他の文字符号化方式に比べてデータ交換可能性が高い。
:# [[UTF-8]]などに比べてサイズが小さい。UTF-8では半角カナや漢字の多くは3バイトを要する。
; 欠点
:# 半角カナのための領域を確保した関係上、区点番号と符号の相互演算には前述のように煩雑な条件分岐が必要である。
:# 2バイト目に未満（[[ASCII]]のコード領域）が現れる。このため、文字の区切りの判定に手間がかかる。ファイルや電文の先頭から文字コードの判定をする場合はよいが、後ろから判定をしようとすると、最悪の場合、先頭までたどらないといけないことがあるため、プログラムの作り方に工夫が必要になる。また、この領域に含まれる一部の文字の扱いのため、マルチバイトのEUC-JP、[[UTF-8]]などに比べ、プログラミング上の扱いが難しい（[[#2バイト目が5C等になりうることによる問題|次項]]を参照）。
:# [[JIS X 0212|JIS補助漢字]]が表現できない。
:# 文字集合については実装ベンダがJIS X 0208で規定されていない機種依存の拡張を施していることが多く、こういった拡張部分に関してはデータ交換可能性が低い。特に広く普及している[[Microsoftコードページ932]]は[[JIS X 0213]]で拡張された[[Shift_JIS-2004]]と併用できない。

=== 2バイト目が5C等になりうることによる問題 ===

Shift_JISでは、カタカナの「ソ」、漢字の「噂」など一部の文字の2バイト目に、を使用している。この符号は[[JIS X 0201]]では[[円記号]]、ASCIIなどでは[[バックスラッシュ]]に該当し、多くのプログラミング言語（[[C言語|C]]、[[Perl]]、[[Bourne Shell]]など多数）では[[エスケープ文字]]と扱う。したがって、ソースコードや文字データの処理においてShift_JISを想定していないプログラミング環境では問題が起こる。この問題は、同じように2バイト目の範囲にを含む[[Big5]]や、まれではあるが[[GBK]]などの[[文字コード]]でも発生しうる。

また、以外についても類似の問題が発生することがある。

* 2バイト目がになる文字（「ポ」「芸」など）。この符号はASCIIでは<code>|</code>（[[バーティカルバー]]）に該当する。[[Unix]]やMS-DOSなどの[[シェル]]上でこの符号は[[パイプ (コンピュータ)|パイプ記号]]と認識され、これらの文字を含むファイルは正常に操作できない。
* 2バイト目が（「ゼ」「深」など）、（「ゾ」「転」など）になる文字。これらの符号はASCIIでは<code>[</code>, <code>]</code>に該当する。そのためこれらの文字は[[正規表現]]と組み合わせて使うことができない。

このようなASCII[[約物]]と同じ符号を含むためにプログラム上で不具合を起こしうるマルチバイト文字を俗に「だめ文字」あるいは「ダメ文字」と呼ぶ。

この問題を回避する伝統的な方法として、以下のようなものがある。

* ソースコード全体を[[EUC-JP]]や[[UTF-8]]などのGL領域と混用のない符号に変換し、実行またはコンパイルする（例：Perl のencodingプラグマ）。
* 5Cを含む文字列を扱う場合、「<code>ソ</code>」→「<code>ソ\</code>」のようにダメ文字の直後にエスケープ文字を挿入することで目的の符号列として認識させる（例：[[Perl]]のSjisソフトウェアや[[JavaScript]]）。
* 文字または文字列として扱わず対象文字および内部表現形式を数値の配列として変換を行い、取り扱う際に文字に復号して扱う（例：PerlのEncodeモジュール）。

; 文字化け例
: マルチバイト非対応環境では、Shift_JISの「構わない」という文字列は「高墲ﾈい」または「高筲ﾈい」に文字化けすることがある。後の文字の2バイト目が[[半角カナ]]「ﾈ」として認識されるため、「い」でデコードが再同期され、後の文字列は正常に表示される。
:
: また、同様に「芸能界」という文字列は「芸矧E」に文字化けする。
: 

== 名称 ==
=== 「シフト」について ===
Shift_JISの「シフト」とは、JIS X 0208の文字集合を分割したうえで8ビット符号空間内に“ずらして配置”して符号化していることを意味する。

他の符号化方式においても、複数の文字集合を[[漢字シフトコード|シフトコード]]で切り替える操作を「シフト」と呼ぶが、これとは異なる。例えば、[[ISO-2022-JP]]は[[エスケープシーケンス]]で漢字と英数字を切り替えることを、[[EUC-JP]]は[[JIS X 0212|補助漢字]]と半角カナをシングルシフトで切り替えることを指す。

また、[[ビット演算]]の「[[ビット演算#ビットシフト|ビットシフト]]」とも関係がない。

=== 別名 ===
「**MS_Kanji**」は、IANAによりShift_JISの別名として割り当てられている。

「**x-sjis'''」は、IANAに「Shift_JIS」が登録される以前にNetscape Navigator 2.0において使っていたエンコーディングの指定子名である。HTMLドキュメントの「charset」の指定にShift_JISの別名として使えるブラウザエンジンがある。

## 脚注

## 関連項目
* Shift_JIS-2004
* JIS X 0208
* EUC-JP
* 文字化け