Windows と Shift_JIS
◆ 複雑
◆ Shift_JIS → Shift_JISX0213 → Shift_JIS-2004
◆ Windows のは Windows-31J
◆ Shift_JIS に追加された IBM と NEC 拡張をマージしたもの
◆ これができてからは CP932 はこれのこと
◆ Shift_JISX0213 と Shift_JIS-2004 は WIndows-31J と互換性なし
◆ 片方でしか使えない文字がある
◆ Shift_JIS → Shift_JISX0213 → Shift_JIS-2004
◆ Windows のは Windows-31J
◆ Shift_JIS に追加された IBM と NEC 拡張をマージしたもの
◆ これができてからは CP932 はこれのこと
◆ Shift_JISX0213 と Shift_JIS-2004 は WIndows-31J と互換性なし
◆ 片方でしか使えない文字がある
Shift_JIS は種類がいろいろあるとは聞いてましたが 複雑ですし そもそも Shift_JIS なんか使わないし必要ならライブラリ任せでいいのであんまり気にしてませんでした
ですが 出力で Shift_JIS 形式にする必要があって 出力したものが読み取れないとか問題が出たので今更ながら調べることになりました
一応 wikipedia にまとまってはいるのですが 歴史的な話やらその他規格名がいっぱいで頭に入ってきません
https://ja.wikipedia.org/wiki/Shift_JIS
https://ja.wikipedia.org/wiki/Microsoft%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9A%E3%83%BC%E3%82%B8932
簡単にまとめると Windows では Shift_JIS ができた頃に CP932 という名前をつけたけど メーカーごとに中身がバラバラだったからまとめたのが Windows-31J らしいです
今ではどこのメーカーでも OS の中身は一緒でデフォルトで入ってるソフトがあるくらいの違いですけど 昔はエンコーディングが違うレベルに違いがあったんですね
ガラケーの絵文字とか機種依存文字みたいのでしょうか
統合時には IBM と NEC が採用していたものをマージして 一部重複もあるようです
名前が Windows-31J なのは Windows 3.1 を出すときに作ったものだからのようです
⇩ は Wiki からコピペですが 昔の Windows には系統があったみたいですね
XP も 7 も 10 も NT 系で それより前にあった DOS 系の最後のバージョンが 3.1 だそうです
日本以外ではもう少し続いたそうですけど
この 3.1 が出たのは 1993 年なのでかなり昔ですね
私がまともに PC 使ったのは XP 以降なので全く知らない時代です
そんな頃に Windows-31J が出てたなら Shift_JIS はこれで統一してくれればいいのにされてないわけです
最初に JIS X 0208:1997 で仕様が定義されて
JIS X 0208 の拡張規格の JIS X 0213 で Shift_JISX0213 が定められて
10 文字追加の改正で Shift_JIS-2004 という名前になったようです
上から 1997 年 2000 年 2004 年なので Shift_JIS-2004 が最新みたいです
それと比べて Windows-31J は 1993 年でこっちは特に変化はないみたいなので互換性はないようです
https://ja.wikipedia.org/wiki/Shift_JIS-2004#Windows-31J%E3%81%A8%E3%81%AE%E9%9D%9E%E4%BA%92%E6%8F%9B
Shift_JIS と言うと こういう Windows 特有の Shift_JIS もありますし Windows 以外の正式な仕様のものもあります
Windows で使われる CP932 という言葉も Windows-31J が出てからは Windows-31J のことですが それまでのはまた別の意味です
Java だとその区別のために Windows-31J のことを MS932 と呼んで IBM は Windows-31J を指す CP943 という別のコードポイントを作ったりで用語が多すぎです
すると whatwg の仕様に沿ってるそうです
https://encoding.spec.whatwg.org/#shift_jis
この仕様はウェブの TextEncoder/TextDecoder に使われるものです
なので TextDecoder でデコードできる Shift_JIS と同じものです (TextEncoder は UTF-8 のみサポート)
Shift_JIS 関係のエンコーディングは Shift_JIS ひとつです
Shift_JIS というエンコーディングには次のラベルがついてます
つまり shift-jis も sjis も ms932 も windows-31j も全部同じものです
実際 Windows くらいでしか使われてない Shift_JIS なのに Windows 以外の仕様に対応させるだけムダってことなんでしょうか
これはこれでありがたいですが もし相手側が Windows-31J 以外の Shift_JIS を作ったり受け取ったりするのなら iconv-lite じゃ対応できなそうです
https://docs.microsoft.com/ja-jp/dotnet/api/system.text.encoding?view=netcore-3.1
Windows ですし Shift_JIS 系は Windows-31J だけのサポートでした
コードページの 932 を指定するか名前で shift_jis を指定します
https://www.php.net/manual/ja/mbstring.supported-encodings.php
SJIS-win は Windows-31J のことだと思うのですが SJIS と CP932 がどれを指しているのかわかりませんでした
エイリアスと書いてない以上 3 つともそれぞれ別物みたいですけど
mbstring のソースコードを見てみると SJIS と SJIS_2004 と CP932 になっていて項目が違いますしよくわかりません
https://docs.python.org/ja/3/library/codecs.html#standard-encodings
最初の Shift_JIS と各版の Shift_JIS 2 種類と Windows の Shift_JIS です
比較に良さそうなのでちょっとした関数を作ってみました
ですが 出力で Shift_JIS 形式にする必要があって 出力したものが読み取れないとか問題が出たので今更ながら調べることになりました
一応 wikipedia にまとまってはいるのですが 歴史的な話やらその他規格名がいっぱいで頭に入ってきません
https://ja.wikipedia.org/wiki/Shift_JIS
https://ja.wikipedia.org/wiki/Microsoft%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9A%E3%83%BC%E3%82%B8932
簡単にまとめると Windows では Shift_JIS ができた頃に CP932 という名前をつけたけど メーカーごとに中身がバラバラだったからまとめたのが Windows-31J らしいです
今ではどこのメーカーでも OS の中身は一緒でデフォルトで入ってるソフトがあるくらいの違いですけど 昔はエンコーディングが違うレベルに違いがあったんですね
ガラケーの絵文字とか機種依存文字みたいのでしょうか
統合時には IBM と NEC が採用していたものをマージして 一部重複もあるようです
名前が Windows-31J なのは Windows 3.1 を出すときに作ったものだからのようです
⇩ は Wiki からコピペですが 昔の Windows には系統があったみたいですね
DOS系 : 1.0・2.x・3.x
9x系 : 95・98・98 SE・Me
NT系 : NT (3.1・3.5x (Citrix WinFrame)・Cairo・4.0)・2000 (Neptune)・XP (x64)・Vista・7・8.x・RT・10
XP も 7 も 10 も NT 系で それより前にあった DOS 系の最後のバージョンが 3.1 だそうです
日本以外ではもう少し続いたそうですけど
この 3.1 が出たのは 1993 年なのでかなり昔ですね
私がまともに PC 使ったのは XP 以降なので全く知らない時代です
そんな頃に Windows-31J が出てたなら Shift_JIS はこれで統一してくれればいいのにされてないわけです
最初に JIS X 0208:1997 で仕様が定義されて
JIS X 0208 の拡張規格の JIS X 0213 で Shift_JISX0213 が定められて
10 文字追加の改正で Shift_JIS-2004 という名前になったようです
上から 1997 年 2000 年 2004 年なので Shift_JIS-2004 が最新みたいです
それと比べて Windows-31J は 1993 年でこっちは特に変化はないみたいなので互換性はないようです
https://ja.wikipedia.org/wiki/Shift_JIS-2004#Windows-31J%E3%81%A8%E3%81%AE%E9%9D%9E%E4%BA%92%E6%8F%9B
Shift_JIS と言うと こういう Windows 特有の Shift_JIS もありますし Windows 以外の正式な仕様のものもあります
Windows で使われる CP932 という言葉も Windows-31J が出てからは Windows-31J のことですが それまでのはまた別の意味です
Java だとその区別のために Windows-31J のことを MS932 と呼んで IBM は Windows-31J を指す CP943 という別のコードポイントを作ったりで用語が多すぎです
プログラミング言語
JavaScript
調べるきっかけになったのは JavaScript の変換だったので iconv-lite を調べてみましたすると whatwg の仕様に沿ってるそうです
https://encoding.spec.whatwg.org/#shift_jis
この仕様はウェブの TextEncoder/TextDecoder に使われるものです
なので TextDecoder でデコードできる Shift_JIS と同じものです (TextEncoder は UTF-8 のみサポート)
Shift_JIS 関係のエンコーディングは Shift_JIS ひとつです
Shift_JIS というエンコーディングには次のラベルがついてます
- "csshiftjis"
- "ms932"
- "ms_kanji"
- "shift-jis"
- "shift_jis"
- "sjis"
- "windows-31j"
- "x-sjis"
つまり shift-jis も sjis も ms932 も windows-31j も全部同じものです
実際 Windows くらいでしか使われてない Shift_JIS なのに Windows 以外の仕様に対応させるだけムダってことなんでしょうか
これはこれでありがたいですが もし相手側が Windows-31J 以外の Shift_JIS を作ったり受け取ったりするのなら iconv-lite じゃ対応できなそうです
.NET
.NET も調べてみましたhttps://docs.microsoft.com/ja-jp/dotnet/api/system.text.encoding?view=netcore-3.1
Windows ですし Shift_JIS 系は Windows-31J だけのサポートでした
コードページの 932 を指定するか名前で shift_jis を指定します
PHP
PHP ではモバイルや Mac の Shift_JIS にも対応してるようですhttps://www.php.net/manual/ja/mbstring.supported-encodings.php
- SJIS
- SJIS-win
- CP932
- SJIS-mac (エイリアス: MacJapanese)
- SJIS-Mobile#DOCOMO (エイリアス: SJIS-DOCOMO)
- SJIS-Mobile#KDDI (エイリアス: SJIS-KDDI)
- SJIS-Mobile#SOFTBANK (エイリアス: SJIS-SOFTBANK)
SJIS-win は Windows-31J のことだと思うのですが SJIS と CP932 がどれを指しているのかわかりませんでした
エイリアスと書いてない以上 3 つともそれぞれ別物みたいですけど
mbstring のソースコードを見てみると SJIS と SJIS_2004 と CP932 になっていて項目が違いますしよくわかりません
Python
Python でもいくつか対応していて これが一番わかりやすい気がしましたhttps://docs.python.org/ja/3/library/codecs.html#standard-encodings
- cp932
- shift_jis
- shift_jis_2004
- shift_jisx0213
最初の Shift_JIS と各版の Shift_JIS 2 種類と Windows の Shift_JIS です
比較に良さそうなのでちょっとした関数を作ってみました
sjis = [
"shift_jis",
"shift_jisx0213",
"shift_jis_2004",
"cp932",
]
def enc(c):
print("encode :", c)
mx = max(map(len, sjis))
for e in sjis:
encoded = ""
try:
encoded = ["%02x" % x for x in c.encode(e)]
except:
encoded = "ERROR"
print(" ", e.ljust(mx), ":", encoded)
def dec(b):
print("decode :", b)
b = bytes.fromhex("".join(b))
mx = max(map(len, sjis))
for e in sjis:
decoded = ""
try:
decoded = b.decode(e)
except:
decoded = "ERROR"
print(" ", e.ljust(mx), ":", decoded)
enc("abcあいう")
dec(["61", "62", "63", "82", "a0", "82", "a2", "82", "a4"])
encode : abcあいう
shift_jis : ['61', '62', '63', '82', 'a0', '82', 'a2', '82', 'a4']
shift_jisx0213 : ['61', '62', '63', '82', 'a0', '82', 'a2', '82', 'a4']
shift_jis_2004 : ['61', '62', '63', '82', 'a0', '82', 'a2', '82', 'a4']
cp932 : ['61', '62', '63', '82', 'a0', '82', 'a2', '82', 'a4']
decode : ['61', '62', '63', '82', 'a0', '82', 'a2', '82', 'a4']
shift_jis : abcあいう
shift_jisx0213 : abcあいう
shift_jis_2004 : abcあいう
cp932 : abcあいう
for ch in "∵∑髙№𠮟噓":
enc(ch)
encode : ∵
shift_jis : ['81', 'e6']
shift_jisx0213 : ['81', 'e6']
shift_jis_2004 : ['81', 'e6']
cp932 : ['81', 'e6']
encode : ∑
shift_jis : ERROR
shift_jisx0213 : ERROR
shift_jis_2004 : ERROR
cp932 : ['87', '94']
encode : 髙
shift_jis : ERROR
shift_jisx0213 : ERROR
shift_jis_2004 : ERROR
cp932 : ['ee', 'e0']
encode : №
shift_jis : ERROR
shift_jisx0213 : ['87', '82']
shift_jis_2004 : ['87', '82']
cp932 : ['87', '82']
encode : 𠮟
shift_jis : ERROR
shift_jisx0213 : ERROR
shift_jis_2004 : ['98', '73']
cp932 : ERROR
encode : 噓
shift_jis : ERROR
shift_jisx0213 : ERROR
shift_jis_2004 : ['ea', 'a5']
cp932 : ERROR