Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

サロゲートペア入門

Vistaから増えたUnicode環境で使用できる日本語漢字の対応方法

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2007/08/28 14:00

Windows VistaのJIS2004対応により、WindowsのUnicode環境で使用できる日本語漢字が907字追加されました。しかしこの中には「サロゲートペア」と呼ばれる文字が含まれており、文字を取り扱うには適切な処理が必要になります。

はじめに

 Windows VistaのJIS2004対応により、WindowsのUnicode環境で使用できる日本語漢字の数が増えました。従来、12238字(Windows XP)だったのが13145字(Windows Vista)になり、907字追加されることになりました。これによって、JIS第3水準、JIS第4水準の漢字がすべてサポートされることになったのです(Windows XPまでは一部サポート)。

 またWindows XPでも、パッチさえ当てれば、Windows Vistaと同じように追加907字を加えた13145字の漢字が使用できるようになりました。

 ところが、この追加された907字の中には「サロゲートペア」という特殊な文字が304字あり、これらは今までのUnicodeの文字とは扱いが少し違います。この点について解説していきたいと思います。

対象読者

  • Unicodeでデータ処理をしている方
  • JIS第3水準、JIS第4水準の文字を扱っている方
  • ブラウザ上でたくさん漢字を使いたい方

 なお、この文書での「Unicode」とは、狭義のUnicode(Windows標準のUTF-16)を指します。他のUnicode符号化方式(UTF-8、UTF-32等)は含みません。

必要な環境

  • Windows Vista または Windows XP
  • サロゲートペアおよびJavaScriptに対応したWebブラウザ(IE7、FireFox2等)

 ただし、Windows XPの場合は、事前に以下のJIS2004対応パッチを適用しておいてください。

サロゲートペアとは?

 通常、Unicodeでは1文字あたり2バイトのデータ量を使います。2バイトですから65536通り(0x0000~0xFFFF)のビットを表現できます。この約6万字で世界中の文字を表現しようというのがUnicodeの本来の思想でした。

 さらに、日本語の処理について言うと、全角・半角に関係なく1文字あたり2バイトのデータ量を使います("a"も"あ"も2バイト)。このため「文字数 × 2 = 使用バイト数」という関係が常に成り立っていて、使用バイト数を2で割れば文字数を簡単に導き出せました。これは文字列からループ文で1文字ずつ処理する場合など、何かと都合がいいことも多かったのです。

 ところが、近年、Unicodeに組み込みたいという文字の要望がいろいろと増えてきました。結果的に従来の2バイト(65536文字)では文字が足りない状況になってしまったのです。そこで、解決策としてサロゲートペアという方法が導入されました。これは、「1文字=2バイト」の基本は維持しつつ、一部の文字については「1文字=4バイト」にする方法です。

 具体的には、従来のUnicodeでは未使用のだった0xD800~0xDBFF(1024通り)を「上位サロゲート」、0xDC00~0xDFFF(1024通り)を「下位サロゲート」と規定し、「上位サロゲート+下位サロゲート」の4バイトで文字を表現する方法です。

 「上位サロゲート」も「下位サロゲート」も従来のUnicodeでは未使用の領域なので、以前のUnicodeの文字コードと重複することはありません。

 このサロゲートペアの導入により1024×1024=1048576字の領域が追加されることになりました。

Windows Vistaで追加された文字

 Windows Vista(JIS2004)で追加された907字の中でサロゲートペアを使用する文字は304字あります。一覧を掲載しておきます。

Windows Vista(JIS2004)のサロゲートペア使用文字
Windows Vista(JIS2004)のサロゲートペア使用文字

 これを見て「おや?」と疑問を持たれた方がいるかもしれません。従来、Unicodeの文字コードは2バイトでしたから「4文字(16進数)」で表現していました。サロゲートペアは4バイトなわけですから、文字コードも倍の「8文字(16進数)」になりそうですが、そうではありません。サロゲートペアの文字コードは「5文字(16進数)」で表現します。

 5文字では4バイトのデータを表現するのには文字が足りないですが、問題はありません。なぜかと言うと、サロゲートペアの文字コードについては、独自の変換規則に従って4バイトのデータへ変換することになっているからです。この変換規則については後ほど説明しますが、とりあえず「サロゲートペアの文字は、文字コードは5文字だけどデータは4バイト」というぐらいで理解しておいてください。

Webブラウザでの表示

 HTMLでは

 "&#x" + [Unicodeの文字コードの16進数表記] + ";"

 と書くとUnicodeの文字コードから文字を表示することができます。

 例えば、「あ Unicode:0x3042」を表示したければ、

あ

 とHTMLソースに書けば「あ」と表示されます。

 同様に、サロゲートペアを使用する文字についてもこの方法が使えます。

 例えば、「叱 Unicode:0x20B9F」の場合、

𠮟

 と書けば表示されます。

文字コードからバイナリデータへの変換規則

 サロゲートペアの文字コードについては、独自の変換規則で4バイトのデータへ変換すると書きました。その変換方法について説明したいと思います。

 具体的には、以下の手順に従います。

  1. 文字コードから0x10000を引いて1番左の桁を"2"から"1"にする。これをXとする。
  2. Xを0x400で割ってその商を0xD800に足す。これを「上位サロゲート」とする。
  3. Xを0x400で割ってその剰余を0xDC00に足す。これを「下位サロゲート」とする。
  4. 上位サロゲート、下位サロゲートの順番で出力する。

 例としてJavaScriptでのサンプルコードを挙げます。

サロゲートペアを使用しない文字の場合:「あ Unicode:0x3042」をダイアログに表示
var x;
var s;
x = 0x3042;  //文字コードをセット
s = String.fromCharCode(x);
alert(s);
サロゲートペアを使用する文字の場合:「叱 Unicode:0x20B9F」をダイアログに表示
var x;
var s;
var a;  //上位サロゲート
var b;  //下位サロゲート
x = 0x20B9F;  //文字コードをセット
x -= 0x10000;
a = Math.floor(x / 0x400);  //Math.floor()で整数値に変換
a += 0xD800;
b = x % 0x400;
b += 0xDC00;
s = String.fromCharCode(a,b);
alert(s);

 このサンプルコードはJavaScriptですが、C言語などでサロゲートペアの文字を入出力する場合も同様の処理が必要になります。

まとめ

 以上で、解説を終わりますが、最後にプログラミングから見たサロゲートペアの問題点を挙げておきたいと思います。

 サロゲートペアを使用する文字は「1文字=4バイト」ですから、従来のUnicodeの特徴であった「文字数 × 2 = 使用バイト数」の原則が崩れてしまいます。そのため、Unicode対応の開発環境であったとしても、サロゲートペアが絡むと過去に作ったプログラムがうまく動かない場合が出てくると思われます。

 開発環境ごとに事情が違うので、そのあたりを確認しながらサロゲートペア対応のプログラムを作成してください。

参考資料

  1. Microsoft『Windows Vista における JIS2004 対応に関する詳細資料
  2. Microsoft『JIS X 0213:2004 / Unicode 実装ガイド』(PDF)
  3. Wikipedia『Unicode
  4. ITpro『Vistaで化ける字,化けない字
  5. ITpro『Vistaで化ける字,化けない字(続報)
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

おすすめ記事

All contents copyright © 2006-2016 Shoeisha Co., Ltd. All rights reserved. ver.1.5