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回だけ押されたのかをプログラムが判別できるようにした。これは当時のアプリケーションソフト（Multiplanなど）でメニュー選択にスペースキーを使用していたためであった。また、プリンターでは全角スペースと半角スペースの幅の比が2対1でない場合があるため、スペースの区別は帳票設計に影響があった。

 標準化 
Shift_JISは ISO 2022の符号化の範囲外にあるベンダー独自の実装として誕生しており、普及後もしばらく標準化されずにいたが、JIS X 0208:1997において附属書1で「シフト符号化表現」という名前で仕様が定義された。また、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では以下のような対応で符号化している。

+ 表: 区点(第1面)とShift_JIS符号化 Shift_JIS 第2バイト(16進) 40 … 7E 80 … 9F … FC 第1バイト(16進) 81 1区1点 1区63点 1区64点 2区1点 2区94点 ⋮ 9F 61区1点 61区63点 61区64点 62区1点 62区94点 E0 63区1点 63区63点 63区64点 64区1点 64区94点 ⋮ EF 93区1点 93区63点 93区64点 94区1点 94区94点

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では以下のように対応している。
+ 表: 区点(第2面)とShift_JIS符号化 Shift_JIS 第2バイト(16進) 40 … 7E 80 … 9F … FC 第1バイト(16進) F0 1区1点 1区63点 1区64点 8区1点 8区94点 F1 3区1点 3区63点 3区64点 4区1点 4区94点 F2 5区1点 5区63点 5区64点 12区1点 12区94点 F3 13区1点 13区63点 13区64点 14区1点 14区94点 F4 15区1点 15区63点 15区64点 78区1点 78区94点 F5 79区1点 79区63点 79区64点 80区1点 80区94点 ⋮ FC 93区1点 93区63点 93区64点 94区1点 94区94点

 区点番号からの変換 
面区点番号 から Shift_JISの 第1バイト・第2バイトは以下の式で求められる。は床関数。

 符号化可能な文字数 
初期の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などに比べ、プログラミング上の扱いが難しい（次項を参照）。
 JIS補助漢字が表現できない。
 文字集合については実装ベンダがJIS X 0208で規定されていない機種依存の拡張を施していることが多く、こういった拡張部分に関してはデータ交換可能性が低い。特に広く普及しているMicrosoftコードページ932はJIS X 0213で拡張されたShift_JIS-2004と併用できない。

 2バイト目が5C等になりうることによる問題 
+ : JIS X 0208で2バイト目にを持つ文字一覧 文字 符号（16進） 読み・字義 文字化け例 ― 815C ダッシュ ソ 835C そ (片仮名) ソフト→ャtト Ы 845C ゥイ (キリル文字) 噂 895C ソン、うわさ 噂話→汚b 浬 8A5C リ、かいり、ノット 欺 8B5C ギ、あざむ-く 詐欺師→詐去t 圭 8C5C ケイ 錦織圭など→錦織撃ﾈど 構 8D5C コウ、かま-える 構成→告ｬ 蚕 8E5C サン、かいこ 養蚕業→養視ﾆ 十 8F5C ジュウ、とお (漢数字の10) 十人十色→署l署F 申 905C シン、もう-す、さる 申請→瑞ｿ、 申込み→錐桙ﾝ 曾 915C ソ、ひ (「曽」の旧字) 曾孫→荘ｷ、 曾祖父→荘c父 箪 925C タン (「簞」の簡易慣用字体) 箪笥→註y 貼 935C チョウ、は-る 貼り付け→唐阨tけ 能 945C ノウ、よ-く、あた-う 能力→迫ﾍ、 可能性→可柏ｫ 表 955C ヒョウ、おもて、あらわ-す 表示→侮ｦ、 代表的→代蕪I 暴 965C ボウ、バク、あば-れる 暴力→沫ﾍ、 暴露→迄I 予 975C ヨ、あらかじ-め、かね-て 予算→落Z、 予想→卵z 禄 985C ロク 元禄X年→元蝋年 兔 995C ト、うさぎ (「兎」の異体字) 喀 9A5C カク、キャク、は-く 喀血する→嚮撃ｷる 媾 9B5C コウ 媾和→尨a （「講和」の非書換え） 彌 9C5C ミ、ビ、や (「弥」の旧字） 和泉元彌など→和泉元怩ﾈど 拿 9D5C ダ 拿捕する→摯ﾟする 杤 9E5C とち (「栃」の異体字) 歃 9F5C ソウ、ショウ、すす-る 血を歃って→血を氓ﾁて 濬 E05C シュン、さら-う 長谷川濬など→長谷川烽ﾈど 畚 E15C ホン、ふご、もっこ 畚に乗る→痰ﾉ乗る 秉 E25C ヘイ、ヒン、と-る 秉燭→竦C 綵 E35C サイ、あや 動植綵絵→動植繩G 臀 E45C デン、しり 臀部など→苺狽ﾈど 藹 E55C アイ 和気藹々→和気蛛X 觸 E65C ショク (「触」の旧字) 軆 E75C タイ (「体」の異体字) 鐔 E85C タン、つば 金鐔焼き→金闖ﾄき 饅 E95C マン 饅頭→體ｪ 鷭 EA5C バン (鳥の名) 鷭の群れ→黷ﾌ群れ
Shift_JISでは、カタカナの「ソ」、漢字の「噂」など一部の文字の2バイト目に、を使用している。この符号はJIS X 0201では円記号、ASCIIなどではバックスラッシュに該当し、多くのプログラミング言語（C、Perl、Bourne Shellなど多数）ではエスケープ文字と扱う。したがって、ソースコードや文字データの処理においてShift_JISを想定していないプログラミング環境では問題が起こる。この問題は、同じように2バイト目の範囲にを含むBig5や、まれではあるがGBKなどの文字コードでも発生しうる。

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

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

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

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

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

 文字化け例
 マルチバイト非対応環境では、Shift_JISの「構わない」という文字列は「高墲ﾈい」または「高筲ﾈい」に文字化けすることがある。後の文字の2バイト目が半角カナ「ﾈ」として認識されるため、「い」でデコードが再同期され、後の文字列は正常に表示される。
{| class="wikitable" style="text-align:center;"
! colspan="2" | 構
! colspan="2" | わ
! colspan="2" | な
! colspan="2" | い
|-
| 8d || style="background: yellow;"| 5c || 82 || ed || 82 || c8 || 82 || a2
|-
| colspan="8" | ▼エスケープ文字にあたる5cが抜けた場合
|-
| 8d || style="background: yellow;"|   || 82 || ed || 82 || c8 || 82 || a2
|-
! colspan="3" | 高
! colspan="2" | 墲
! ﾈ
! colspan="2" | い
|}
 また、同様に「芸能界」という文字列は「芸矧E」に文字化けする。
 {| class="wikitable" style="text-align:center;"
! colspan="2" | 芸
! colspan="2" | 能
! colspan="2" | 界
|-
| 8c || 7c || 94 || style="background: yellow;"| 5c || 8A || 45
|-
| colspan="6" | ▼エスケープ文字にあたる5cが抜けた場合
|-
| 8C || 7c || 94 || style="background: yellow;"|   || 8A || 45
|-
! colspan="2" | 芸
! colspan="3" | 矧
! E
|}

 名称 

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

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

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

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

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