3
4

More than 1 year has passed since last update.

文字コードの5C問題について解説

Posted at

最近直面した5C問題をメモとしてまとめておこうと思います。

5C問題とは

日本語は、ひらがな、カタカナ、漢字など文字数も多く、1バイト(256種類)では
すべての文字を表現することは難しいため、ShiftJISでは、漢字を1文字当たり2バイト
使って文字情報を表します。

ここで問題なのが、「¥」「 \ 」の文字コードが「5c」であり、
一部の漢字の文字コードが重複しているため、コンピュータはその箇所を
エスケープ記号として解釈することにより正常に読み取れなくなっている。

文字 Shift-JISコード
89 5c
97 5c
99 5c

こちらの文字コード表を参考

コードで確認

PHPでShiftJISの「兔」の文字の値を見てみる。

php
$str = mb_convert_encoding('兔', 'SJIS', 'UTF-8');
var_dump($str);
// 出力結果: string(2) "�¥"

エスケープ文字の「¥」が表示された。
これは、コンピュータが「兔」の文字コード「5c」の箇所を「¥」として
解釈したためである。
このままの状態でプログラムを書くと予期せぬエラーが発生する可能性がある。

想定されるエラー

例として、CSVデータ取得処理のときファイルがShift-JIS
特定の文字を使っているときを想定し、PHPのfgetcsvメソッドを使用してデータを取得する。

php
$temp = tmpfile();
$str = mb_convert_encoding('"兔"', 'SJIS', 'UTF-8');
var_dump($str);
// 出力結果: string(4) ""�¥""
fwrite($temp, $str);
var_dump(fgetcsv($temp));
// 出力結果: bool(false)

$strの値には""�¥""がはいっており、これを解釈すると
「¥」の次の「"」がエスケープされ、形式が崩れてしまうことで
fgetcsvメソッドfalseを返してしまう。

回避するには

  • 文字コードをShiftJISUTF-8へ変換する。
  • 各言語で変換するためのロジックを組む必要がある。

PHPであれば、file_get_contentsメソッドでファイル全体を文字列に読み込んだ後に
mb_convert_encodingメソッドUTF-8へ変換する。

又は、ストリームフィルタ機能を使ってphp_user_filterクラスを継承したクラスを
生成した後にfilterメソッドを定義して変換する処理を書く。

感想

文字コードの問題は頭の片隅に置いといて
ファイル読み込みの際は、対策を考慮しないといけないですね。

ストリームフィルタを作るのは結構大変そうなので
調べて別の記事に注意点などメモとしてまとめたいなと思います。

3
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4