SJISはShift_JISのエイリアスじゃない

人事労務freeeのエンジニアのスポーンです。

RubyでShift_JISに変換するときにハマったので、同じことをしようと思った人の参考になれば幸いです。

Rubyのエンコード

要件として、入力文字列の文字コードをShift_JISにエンコードする必要がある機能がありました。 RubyではString.encode()メソッドでエンコードを変更できるので、以下のようなコードを書きました。

''.encode('SHIFT_JIS')

その後、リファクタリングをしている時についでに

''.encode('sjis')

と変更してみたところエラーで落ちてしまいました。

SJISとShif_JISの違い

github.com

上記がRubyの String.encode() の引数部分のエイリアス実装箇所です。 実装によると

ENC_ALIAS("SJIS", "Windows-31J")

このように実装されており、SJISSHIFT_JISのエイリアスではなく、 Windows-31J のエイリアスと分かります。

p Encoding.aliases でエイリアス一覧が取得できるので、そちらでも確認できます。

Windows-31Jとは

Windows-31JはShift_JISをマイクロソフト以外の企業が独自拡張した文字コードを統合し、標準化した文字コードのようです。

Microsoft コードページ 932(CP932)は、マイクロソフト及び、MS-DOSのOEMベンダがShift_JISを独自に拡張した文字コードである。また同時に、CP932はShift_JISのWindowsアプリケーションにおける「実装」を指す用語であるとも言える。

(中略)

マイクロソフトは1993年、Windows 3.1の日本語版を出すにあたり、「CP932の誕生と発展」節で述べたように多様化した「CP932」の仕様をOEMメーカーの自由に任せるという方針を撤回した。日本のパーソナルコンピュータ市場で、特に大きなシェアを持つ上記2社の統合コードをWindowsにおける日本語標準コードとし、また、これをIANAに「Windows-31J」という名で登録した。IANA登録名の「Windows-31J」とは、読んで字のごとく、「Windows3.1 Japanese」を意味している。

Microsoftコードページ932 - Wikipedia

代表的なShift_JISとの差分としては、人名で言うと

  • 「髙橋」さんの髙(はしごだか)
  • 「齋藤」さんの齋(斎の旧字体)

などがあります。

特に人名で使われる漢字の旧字体はShift_JISにはなく、Windows-31Jにしか無い文字コードの可能性があるので注意が必要です。

まとめ

人事労務freeeでは電子政府窓口e-Govなど、行政サービスと連携をした機能の開発をしています。

普段サービス内で扱っているデータはUTF-8なので、文字コードを意識することはありませんが、行政サービスなどのShift_JISが指定されている連携先は、 こういった問題が発生するため、文字コードについてしっかりとした理解が必要だと、学びがありました。

日本語を含む文字コードについては以下のサイトが詳しいため、参考になりました