文字化け

QRコードは、元々Shift-JIS(正確にはJIS X 0208)の文字を扱うことを想定されていましたが、国際的に普及することにより、UTF-8(Unicode)の文字を扱うことが増えてきました。
複数の文字コードが登場してくると、切っても切り離せないのが「文字化け」です。


UTF-8とは

UTF-8は、一言で表すと、Unicodeの表現方法の一種です。
Unicodeは、世界中の文字を統一したコードで表そうとした文字集合で、1つ1つの文字に、0番からの番号が振られています。(この番号をコードポイントといいます。)
0から127までのコードポイントは、AsciiShift_JISと同じ番号になっています。
Unicodeは、約111万文字を収録できる領域があり、今後のために、まだ全てが使われていません。2016年現在で、約1/4が使用されています。

Unicodeのコードポイントの数字をそのままデータとして扱おうとすると、いろいろな問題が生じることが分かりました。
・固定長のデータにする場合、最低でも3バイトの領域が必要になる。(当初の想定でも2バイト)
・Asciiの文字しか使わない英語圏の人にしてみると、データ量が3倍(当初の想定でも2倍)になってしまう。
・データの途中の1バイトだけを見ると、その1バイトが文字の先頭か末尾か真ん中かが分からない。

そのため、Unicodeを1バイトから4バイトの可変長で表現する方法(符号化方式) UTF-8 が作成されました。
(当初は最大6バイトでしたが、4バイトまでに短縮されました。)
UTF-8により、上記の問題が解消されました。
・固定長のデータにせず可変長とすることで、最低が1バイトで表現できる。
・Ascii(0〜127番)の文字しか使わない場合、Asciiと全く同じデータになり、データ変換の必要がない。
・データの途中の1バイトだけを見て、それが文字のどの部分かわかるよう工夫されている。

Unicodeの符号化方式には、UTF-8以外にも、UTF-16、UTF-32 等があります。
UTF-8は上記のように利点が大きいため、近年UTF-8はURLエンコードやテキストファイル保存の形式等、広く使用されています。


QRコードのデータ構造

QRコードでは、データを4種類のモード(数字英数字バイナリ漢字)のいずれか、またはこれらの組合せで格納します。

Shift_JISのQRコードは、

数字モード:1バイトの 0〜9
英数字モード:1バイトの 0〜9、A〜Z、一部の記号
漢字:JIS X 0208の文字(全角記号、全角数字、ひらがな、カタカナ、漢字)
バイナリ:a〜z、上記以外の1バイトの記号、上記以外の2バイト文字をShift_JIS形式で保存

となっています。

UTF-8のQRコードは、

数字モード:1バイトの 0〜9
英数字モード:1バイトの 0〜9、A〜Z、一部の記号
漢字:JIS X 0208の文字(全角記号、全角数字、ひらがな、カタカナ、漢字)
バイナリ:a〜z、上記以外の1バイトの記号、上記以外のUnicodeを2〜4バイトのUTF-8形式で保存

となっています。

1つのモードにつき、[モード識別データ][文字長識別データ][実際のデータ] の形でセットとなっていて、QRコードには、これらのセットが単一または複数存在します。

easyQRでは、UTF-8を選択すると、数字、英数字、8ビットバイト(UTF-8)、またはこれらの混在モードのQRコードを生成します。漢字モードは使用しません。


QRコードで文字化けが発生する理由

上記のように、Shift_JISのQRコードUTF-8のQRコードではバイナリモードへの保管方法が異なります。
そのため、そのQRコードを携帯電話、スマホ、QRコードリーダーで読み込んだ時に正しく解釈できるかどうかは、機器に搭載されたソフトウェア(スマホの場合はスマホアプリ)に依存します。
機器内のソフトウェアやスマホアプリが、バイナリデータを正しく解釈できなかったり、その仕様がサポートされていない場合に、文字化けが発生することになります。


UTF-8のQRコードで発生する文字化け

UTF-8のQRコードをガラケーで読み込ませると、ガラケーのソフトウェアがUTF-8のQRコードに対応していないため、バイナリデータ部分に含まれる日本語などが文字化けます。

文字化けの例
UTF-8abcdef
バイナリ(16進数)0x610x620x630xe30x810x820xe30x810x830x640x650x66
Shift-JISabcdef


上記の例のように、[abcあいdef] というUTF-8のQRコードを作成し、Shift-JISとしてしか解釈できないガラケーで読み込ませると、[abc縺ゅ>def] と解釈され、文字化けて表示されることになります。


Shift-JISのQRコードで発生する文字化け

Shift-JISのQRコードをスマホアプリで読み込ませると、たいていの場合は正しく読み込めるようです。(10種類のQRコードリーダーのアプリで検証)
たまにUTF-8と判断されて文字化けが発生する場合もありますが、バージョンアップで改善されることが多く、バグ修正として対処されているようです。

また、各キャリアの絵文字については、Shift-JISの外字領域が使用されています。外字は基本的に、Unicodeには収録されません。こういった絵文字を正しく表示するには、ソフトウェア側でUnicode絵文字に置き換える必要があります。
しかしながら、スマホアプリでは変換されないようですので、各キャリアの絵文字は文字化けしてしまいます。(10種類のQRコードリーダーのアプリで検証)


easyQRのUnicode対応

easyQRでは、テキストボックスにUnicode文字(非Shift-JIS文字)を入力することができません。その代わりに、独自のUnicode表現を使って入力することができます。
Unicodeのコードポイントを [+0000] 〜 [+FFFD] または [1F000] 〜 [1FFFF] の形式で直接入力することで、Shift-JISに無いUnicode文字を入力することができます。
これらの範囲を外れた領域にもUnicode文字は存在しますが、それらの文字は入力できません。
日本語、英語、および絵文字を入力する分には問題ないと考えています。