結論:
- Python で Shift_JIS 読もうとして UnicodeDecodeError 出たときは
'cp932'一択です。 Never use'shift_jisx0213'! - ググる前に ドキュメント を読め‼
日本語 Windows*1 のメモ帳に環境依存文字 \~①Ⅰⅰ咩﨑瀨髙 を貼り付けてANSI文字コード *2 で保存したら、
% od -tx1 -Ax sjis.txt 0000000 5c 7e 87 40 87 54 fa 40 fa 93 fa b1 fb 50 fb fc 0000010
というバイト列になります。これを codecs ライブラリで 'shift_jis', 'shift_jisx0213', 'shift_jis_2004', 'cp932'(= 'ms932')と指定して読み込んでみましょう。
% /Library/Frameworks/Python.framework/Versions/3.6/bin/python3
Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 26 2018, 19:50:54)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> codecs.open('sjis.txt',"rb",'Shift_JIS').read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/codecs.py", line 700, in read
return self.reader.read(size)
UnicodeDecodeError: 'shift_jis' codec can't decode byte 0x87 in position 2: illegal multibyte sequence
>>> codecs.open('sjis.txt',"rb",'Shift_JISx0213').read()
'¥‾①Ⅰ豗迠郫鍚騠'
>>> codecs.open('sjis.txt',"rb",'Shift_JIS_2004').read()
'¥‾①Ⅰ豗迠郫鍚騠'
>>> codecs.open('sjis.txt',"rb",'cp932').read()
'\\~①Ⅰⅰ咩﨑瀨髙'
'shift_jisx0213', 'shift_jis_2004' を使うと丸付き数字①や大文字ローマ数字Ⅰは合っていますが、立ち崎、はしご高、など名字に使われるIBM拡張文字、バックスラッシュやチルダが文字化けします。バックスラッシュ 0x5c が円記号 U+00A5 に化けているのでとても困りますね。
Shift_JIS-2004 では第2面の文字を F0-FC を第一バイトとするコードに割り当てました。その結果、Shift_JIS-2004 を採用すると 115-119区のIBM拡張文字も別の文字に替わってしまいます。
Shift_JIS系文字一覧イメージとSJIS・MS932・CP943の違い - instant tools
(JIS X 0213ベースの拡張Shift_JIS)あえて使うことはほとんどない。
Windows Vista 以降 文字集合 JIS X 0213(:2004) に対応したという情報*3 があったり、丸付き数字やローマ数字が変換に成功しただけで Shift_JIS の代わりに Shift_JIS X 0213(:2004) を使おうという誤解が多々見受けられます。
- UnicodeDecodeError: 'shift_jis' codec can't decode bytes in position - Qiita
- Python での shift_jis と shift_jis_2004 について - Qiita
- shift_jisでUnicodeDecodeErrorが出る場合は、shift_jisx0213でデコードしてみる - minus9d's diary
しかし、Shift_JIS X 0213(:2004) を採用したシステムは非常に稀であり、私は知りません。どなたかご存知だったら教えてください。例えばブラウザでも macOS 版 Safari が Shift_JIS_X0213-2000 に対応しているのみです。
*1:Windows 10 の場合、システム ロケールを日本語 (日本) にして、「ベータ:ワールドワイド言語サポートで Unicode UTF-8を使用」をオフにしている状態。私は普段これを有効にしているが、今回の実験のためにオフにした。
*2:HTTP/HTMLの世界でいう Windows-31J
*3:Windows Vista は(Unicode に JIS X 0213:2004 が含まれているし)フォントを JIS X 0213:2004 の例示字体に合わせていることをもって JIS X 0213:2004 対応したって言ってる感じですか?? 小形克宏の「文字の海、ビットの舟」