Unicode波型問題 CP932とShift_JISは同じエンコーディングではない
「〜」の文字コードはShift_JISで'\x81\x60'で、CP932でも同じコードです。
が、Unicodeには、「波型」と「全角ティルダ」という二つの異なる「〜」が存在します。一般的には「波型」であるu'\u301c'が使われます。Shift_JISの「〜」'\x81\x60'はUnicodeの「波型」にマップされています。
'\x81\x60'.decode('SJIS') == u'\u301c'
「全角ティルダ」のu'\uff5e'は使われない文字なのかと思いきや、
'\x81\x60'.decode('CP932') == u'\uff5e'
Windowsのネイティブ文字コードセットであるCP932(Shift_JISをベースとした独自拡張)では、「〜」'\x81\x60'はUnicodeでいうと「全角ティルダ」u'\uff5e'にあたるそうです。この点において、CP932はShift_JISと互換性のある文字エンコーディングではありません。
CP932はちょっと変わったエンコーディングで、こんな特性があります。
u'\u301c'.encode('CP932') == u'\uff5e'.encode('CP932') == '\x81\x60' '\x81\x60'.decode('CP932') == u'\uff5e'
うへ! 恒等変換じゃない。
u'\uff5e'はShift_JISにマッピングできないので注意。
u'\u301c'.encode('SJIS') #これはOK u'\uff5e'.encode('SJIS') #これはNG #UnicodeEncodeError: 'shift_jis' codec can't encode character u'\uff5e' in position 0: illegal multibyte sequence
ややこしや
Windowsから入ってきた正体不明の日本語テキストは、CP932で解釈してからSJISで保存すると素性のいいものになるかも。
regular_japanese_text = untrusted_unicode.encode('CP932').decode('SJIS')