やる気がストロングZERO

やる気のストロングスタイル

文字コードの円記号問題を復習したのでメモ。

文字コードの円記号問題を復習したのでメモ。

円記号問題

参考)
円記号 - Wikipedia

ざっくり

例えばmacvscodeにて、文字コードをshift-jisに設定して[¥]を入力して保存したあと、一度閉じて再度Shift JIS指定で開くと[¥]で保存したはずなのに[\]が表示されている。

何故こんなことが起こるのかというと、shift-jisでは[¥]と[\]は同一の文字であるから。
文字を表すバイト列は[¥]も[\]も5cになる。

バイト列5cを[¥]として表示するか、[\]として表示するかはフォントやエディタによりけりという感じ。

つまり、shift-jisで[¥]と入力すると、5cというバイト列で保存され、次に読み込みされた際には[\]として表示されたという感じ。

shift-jisとUnicode間での変換を行う際の問題

shift-jisに対して、unicodeでは[¥]と[\]はバイト列が異なる。 utf-8において、[¥]は5cになり、[\]はc2a5になる。

unicodeとshift-jisで1:1で対応していない状況なので変換を行うと問題がおこる。

unicodeで[¥\]と入力した文字列をshift-jisに変換して、再度unicodeに戻すと[\\]になってしまう。

これは、shift-jisに変換した際、[¥]と[\]の区別がないので両方とも[\(5c)]に変換されて区別がなくなってしまう。 その後、再度utf-8に変換する際には[\]に変換され、結果[¥\]は[\\]になってしまう。

フォントによって(主にWindows環境)は[\]は[¥]と表示されている

ややこしいが、[\]は歴史上の問題で主にWindows環境では[¥]と表示されている場合が多い。 Windowsでこの記事を見たら意味わからないことになっていそう。。(ブラウザ用のフォントはいい感じになってたりするのかも?)

バイト列を確認したりいじったりする方法

上記のように[\]と[¥]で見た目がフォントによっては全く同じだったりするので、どちらが出力されているのかはバイト列で確認するのが確実。

以下のテキストのバイト列を確認するには、

\
¥

以下のようにコマンドを叩く。

od -tx1 sample.txt
0000000    5c  0a  c2  a5                                                
0000004

まず[\](5c)が出力されており、次にLF(0a)が出力されて改行され、次に[¥] (a5)が出力されていることがわかる。
バイナリエディタを使えば、直接文字コードを打って表示を確認することもできる。

参考図書(かなり面白かった)