Unicode

出典: フリー百科事典『ウィキペディア(Wikipedia)』
サロゲートペアから転送)
ナビゲーションに移動 検索に移動
この項目には、JIS X 0213:2004 で規定されている文字が含まれています(詳細)。
New Unicode logo.svg

Unicode(ユニコード)は、符号化文字集合文字符号化方式などを定めた、文字コードの業界規格である。文字集合(文字セット)が単一の大規模文字セットであること(「Uni」という名はそれに由来する)などが特徴である。

1980年代に、Starワークステーションの日本語化 (J-Star) などを行ったゼロックス社が提唱し、マイクロソフトアップルIBMサン・マイクロシステムズヒューレット・パッカードジャストシステムなどが参加するユニコードコンソーシアムにより作られた。国際規格のISO/IEC 10646とUnicode規格は同じ文字コード表になるように協調して策定されている[1]

概要[編集]

Unicode は世界で使われる全ての文字を共通の文字集合にて利用できるようにしようという考えで作られ、UnixWindowsmacOSPlan 9[注釈 1]Javaなどで利用されている。現代の文字だけでなく古代の文字や歴史的な文字、数学記号、絵文字なども含む[2]

Unicode以前の文字コードとの相互運用性もある程度考慮されており、歴史上・実用上の識別が求められる場合には互換領域がとられ、元のコード→Unicode→元のコードというような変換(ラウンドトリップ変換)において、元通りに戻るよう配慮されている文字もある。しかし、正規のJIS X 0208の範囲内であればトラブルは少ないが、複数の文字集合が混在したり、Shift_JISの実態であるCP932EUC-JPの亜種であるCP51932とeucJP-MSなど、対応が違うために文字化けを起こすことがある。

Unicode文字符号化モデル[編集]

文字コードは、Unicode文字符号化モデル[3]によると以下の4段階に分けられる。

  • 抽象文字集合ACR):符号化の対象とする順序のない文字の集合。
  • 符号化文字集合CCS):抽象文字集合を非負整数に対応させたもの。この非負整数の範囲を符号空間、各値を符号位置といい、抽象文字は対応後、符号化文字となる[4]。抽象文字は複数の符号化文字に対応されることもある(異体字セレクタ[5]
  • 文字符号化形式CEF):符号化文字集合の非負整数を符号単位列に変換する方法。文字符号化形式はコンピュータ中に実際にデータとして文字を表現することを可能にする。
  • 文字符号化方式CES):符号単位列をバイト列に直列化する方法。符号単位が8ビットより大きい場合はエンディアンが関係する。

その後バイト列を、gzipなどで圧縮したり、7ビット伝送路に通すためBase64Quoted-printableなどで変換することがあるが、これらは文字コードの範囲外である。

文字集合[編集]

Unicodeの文字集合の符号空間は0 - 10FFFF16で111万4112符号位置がある[6]。Unicode 12.1(2019年5月7日公表)では13万7929個(12%)の文字[注釈 2]が割り当てられ、65個を制御文字に使い、13万7468符号位置(12%)を私用文字として確保している。また、2048文字分をUTF-16のための代用符号位置に使用しており、加えて66の特別な符号位置は使われない。残りの83万6536符号位置(75%)は未使用である[7]

文字を特定する場合にはUnicode符号位置や一意につけられた名前が使われる。例えば「a」はU+0061 (LATIN SMALL LETTER A)、「♪」はU+266A (EIGHTH NOTE)である。Unicode符号位置を文章中などに記す場合は "U+" の後に十六進法で符号位置を4桁から6桁続けることで表す。また、符号空間のうち代用符号位置を除く符号位置をUnicodeスカラ値という[8]

収録されている文字は、各国で標準として規定されている文字集合や実際に使用されている文字を持ち寄り、委員会により取捨選択されている。日本の文字については当初より JIS X 0201JIS X 0208JIS X 0212を、Unicode 3.1 からは JIS X 0213 の内容も収録している。

また収録において、元の各文字集合内で分離されている文字は尊重するが、異なる文字集合に同一の文字が収録されているとみなされるものは、同じ符号位置に割り当てる方針を取っている。この際に集合が膨大であるという理由で、漢字について、中国日本韓国の各規格の漢字を統合英語版CJK統合漢字としたことは大きな議論となった。

Unicodeに収録されている文字については、「ブロックの一覧」を参照。

文字符号化形式[編集]

Unicode 12.1(2019年5月7日公表)では文字符号化形式としてUTF-8UTF-16UTF-32の3種類が定められている。

UTF-8は1符号化文字を1〜4符号単位で表す可変幅文字符号化形式で、1符号単位は8ビットである。

UTF-16は1符号化文字を1〜2符号単位で表す可変幅文字符号化形式で、1符号単位は16ビットである。基本多言語面の文字を符号単位一つで、その他の文字をサロゲートペア(代用対)という仕組みを使い符号単位二つで表現する。

UTF-32は1符号化文字を1符号単位で表す固定幅文字符号化形式で、1符号単位は32ビットである。ただし、Unicodeの符号空間がU+10FFFFまでであるため、実際に使われるのは21ビットまでである。

文字符号化方式[編集]

文字符号化形式
(CEF)
文字符号化方式
(CES)
UTF-8 UTF-8
UTF-16 UTF-16
UTF-16BE
UTF-16LE
UTF-32 UTF-32
UTF-32BE
UTF-32LE

Unicode 12.1(2019年5月7日公表)では文字符号化方式としてUTF-8UTF-16UTF-16BEUTF-16LEUTF-32UTF-32BEUTF-32LEの7種類が定められている。それぞれの文字符号化形式に対応する文字符号化方式は表の通り。

文字符号化形式との違いは、文字符号化形式がプログラム内部で文字を扱う場合に符号なし整数として文字を表現する方法なのに対し、文字符号化方式は入出力時にバイト列として表現する方法である。UTF-8は符号単位が8ビットであるため区別する意味はない。

文字符号化方式
(CES)
エンディアン BOMの付与
UTF-8 N/A
UTF-16 ビッグ/リトル
UTF-16BE ビッグエンディアン 不可
UTF-16LE リトルエンディアン 不可
UTF-32 ビッグ/リトル
UTF-32BE ビッグエンディアン 不可
UTF-32LE リトルエンディアン 不可
UTF-8
可変長(1-4バイト)の8ビット符号単位で表現する文字符号化方式。ASCIIに対して上位互換となっており、文字の境界が明確である、UTF-16符号化方式やUTF-32符号化方式との変換・逆変換に際して乗除算などの高負荷処理が必要ない、などの特長を持ち、インターネットではもっとも一般的に利用されている。
なお、UTF-8はもともと8ビットを符号単位とするためBOM(バイト順マーク;後述)は必要ないが、UTF-8であることが識別できるよう、データストリームの先頭に EF BB BF(U+FEFFのUTF-8での表現)の3バイトが付与されることがある。UTF-8のBOMはバイト順を表すものではなく、UTF-16符号化方式等における「真の意味でのBOM」と同じコードポイントを利用しているがゆえに慣用的にこう呼ばれているに過ぎない。UTF-8でのBOMの使用は非推奨[9]
UTF-16
UTF-16符号化方式では、通常はファイルの先頭にバイト順マーク (BOM) が付与される。BOMとは、通信やファイルの読み書き等、8ビット単位の処理でバイト順を識別するための印であり、データストリームの先頭に付与される。値はU+FEFF。システムが読み込んだ先頭2バイトが FF FEならリトルエンディアン、FE FFならビッグエンディアンとして後に続く文書を処理する。
RFC 2781 ではBOMが付いていないUTF-16文書はビッグエンディアンとして解釈することになっている。Windowsのメモ帳で作成した「Unicodeテキスト」はBOMが付与されるようになっている。ビッグエンディアンの符号化方式をUTF-16BE、リトルエンディアンの符号化方式をUTF-16LEとして区別することもある。プロトコルもしくはアプリケーションの設定などの手段で符号化方式にUTF-16BEUTF-16LEを指定している場合にはBOMを付与することは許容されない。Windows上の文書における「Unicodeテキスト」は特に明記のない場合、リトルエンディアンのUTF-16符号化方式のことを指す。TCP/IPネットワークでは、プロトコルヘッダやMIME等の手段で符号化方式が指定されずBOMも付与されない場合、ビッグエンディアンとして扱うと決められている。
UTF-32
UTF-32符号化方式でもUTF-16符号化方式と同じく、ビッグエンディアンとリトルエンディアンが存在し、それぞれUTF-32BEUTF-32LEと呼ばれる。プロトコルもしくはアプリケーションの設定などの手段で符号化方式にUTF-32BEUTF-32LEを指定している場合にはBOMを付与することは許容されない。
単純な符号化方式であるが、テキストファイルなどではファイルのサイズが大きくなる(すべてBMPの文字からなる文章の場合はUTF-16符号化方式の2倍、すべてASCII文字の場合はASCII/UTF-8の4倍のサイズとなる)ため、ストレージ用として使われることは稀である。そのためか、Microsoft Officeでの「エンコードされたテキストファイル」の読み書きでは、Office 2016 でもいまだに符号化方式には対応していない。フリーウェアシェアウェアテキストエディタのうち多数の符号化方式に対応しているものでも、この符号化方式には対応していないものが存在する。
ただし、すべてのUnicode文字を処理する場合には、すべての文字を単一の符号単位で表現したほうが処理に適するため、内部の処理ではUTF-32符号化形式(あるいはUCS-4)で扱うこともある。実例として、Linux 上のC言語環境では wchar_t は32ビット整数型である。
UTF-16符号化方式などと同様にUTF-32符号化方式にもBOMがあり、データストリームの先頭に付される。先頭の4バイトがFF FE 00 00ならリトルエンディアン、00 00 FE FFならビッグエンディアンになる。UTF-16のリトルエンディアンとUTF-32のリトルエンディアンは最初の2バイトが等しいため、4バイトまで読んで判断する必要がある。
各文字符号化方式の符号化例
UTF-8 A Ω 😊
41 CE A9 E8 AA 9E F0 9F 98 8A
UTF-16BE A Ω 😊
00 41 03 A9 8A 9E D8 3D DE 0A
UTF-16LE A Ω 😊
41 00 A9 03 9E 8A 3D D8 0A DE
UTF-32BE A Ω 😊
00 00 00 41 00 00 03 A9 00 00 8A 9E 00 01 F6 0A
UTF-32LE A Ω 😊
41 00 00 00 A9 03 00 00 9E 8A 00 00 0A F6 01 00

その他[編集]

UTF-7
UTF-16で表したUnicodeをBase64で変換して表す符号化方式。ただし、ASCIIのアルファベット範囲等についてはBase64に変換しない等、特殊な符号化方式を行う。RFC 2152で定められており、Unicode規格及びUnicodeの関連規格には含まれない。かつてのSMTP等のように、7ビット単位でしかデータを扱えない通信方式を利用する場合を想定して作られている。ステートフルエンコーディングであり、運用上問題が多いため、現在ではこの方式は推奨されていない。Unicode文字を7ビット単位伝送通信にどうしても通さなければならない場合は、替わりにUTF-8をQuoted-printableあるいはBase64で変換するなどの方式が好ましい。


以下はエイプリルフールに公開されたジョークRFCである (RFC 4042)。UTF-9に関しては同名の規格が実際に検討されていた(ただし、内容は大きく異なる)が、ドラフト段階で破棄されているため重複にはならない。

UTF-9
可変長の9ビット符号単位で表現する符号化方式。1バイト8ビットオクテット)ではなく9ビット(ノネット)であるような環境での利用を想定している。UTF-8と比較した場合、Latin-1領域が1バイト、CJK統合漢字領域が2バイトで表現できる特長があり、データ量が少なくなる。ワード長が9の倍数のコンピュータ(PDP-10ACOS-6など)であれば計算コストも低い。
UTF-18
Unicode符号位置を単一の18ビット符号単位で表現する符号化方式。UTF-8に対するUTF-16のようなものだが、RFC公開時点のUnicodeで文字が定義されていた4つの(BMP、U+1xxxx、U+2xxxx、U+Exxxx)を余った2ビットで識別するため、代用符号位置は使わない。

以下はドラフト段階で破棄された規格案。

UTF-5
国際化ドメイン名での利用を想定し、0-9、A-Vの32文字で表現する文字符号化方式。国際化ドメイン名にはPunycodeが採用されたため、利用されていない。
UTF-9
可変長(1-5バイト)の8ビット符号単位で表現する文字符号化形式または文字符号化方式。ISO-8859-1に対して一部互換である。しかし、UTF-8が普及しつつあり、それと比べて欠点がいくつかあったため、破棄された。

拡張領域[編集]

1980年代の当初の構想では、Unicodeは16ビット固定長で、216 = 6万5536 個の符号位置に必要な全ての文字を収録する、というもくろみであった。しかし、Unicode 1.0公表後、拡張可能な空き領域2万字分を巡り、各国から文字追加要求が起こった。その内容は中国、日本、台湾、ベトナム、シンガポールの追加漢字約1万5千字、古ハングル約5千字、未登録言語の文字などである。このようにしてUnicodeの、16ビットの枠内に全世界の文字を収録するという計画は早々に破綻し、1996年のUnicode 2.0の時点で既に、文字集合の空間を16ビットから広げることが決まった。この時、それまでの16ビットを前提としてすでに設計されていたシステム(たとえばJavaのchar型や、Windows NTWindows 95のAPI)をなるべくそのままにしたまま、広げられた空間にある符号位置を表現する方法として、サロゲートペアが定義された。

サロゲートペア[編集]

サロゲートペア(代用対)は16ビットUnicodeの領域1024文字分を2つ使い(前半 U+D800 〜 U+DBFF、後半 U+DC00 〜 U+DFFF)、各々1個ずつからなるペアで1024 × 1024 = 1,048,576文字を表す。これはちょうど16面分であり、第1面〜第16面(U+10000 〜 U+10FFFF)の文字をこれで表すこととした。加えて第0面(基本多言語面)も使用可能なので、Unicodeには合計で 1,048,576 + 65,536 - 2,048 = 111万2,064文字分の空間が確保されたことになる。Unicodeの符号空間が10FFFF16まで(サロゲート領域を除いて111万2064文字)とされているのはUTF-16が表現可能な限界だからである。

サロゲートはUnicodeの符号位置の U+10000 〜 U+10FFFF の範囲を16ビットユニットのペア(2つ)で表現する集合で、最初の16ビットユニットを前半サロゲートもしくはハイサロゲート、二番目を後半サロゲートもしくはローサロゲートと称する。ハイサロゲートは U+D800 〜 U+DBFF の範囲、ローサロゲートは U+DC00 〜 U+DFFF の範囲である。

サロゲートペアはUTF-16でのみ使われ[10]、UTF-8、UTF-32ではすべての符号位置を符号化できるためこのような特別な処理は必要ない。

コーディング[編集]

サロゲートのエンコーディングは、

       $hi = ($uni - 0x10000) / 0x400 + 0xD800;
       $lo = ($uni - 0x10000) % 0x400 + 0xDC00;

デコーディングは、

       $uni = 0x10000 + ($hi - 0xD800) * 0x400 + ($lo - 0xDC00);

となる。

コード変換例

𠮷」U+20BB7 (下の棒が長い「吉」。つちよし。) のエンコードを考えてみる。

 0x20BB7 (0010 0000 1011 1011 0111) から
 0x10000 (0001 0000 0000 0000 0000) を引くと、結果は
 0x10BB7 (0001 0000 1011 1011 0111) となる。
 
これを上位10ビット値と下位10ビット値に分割する。 0001 0000 10 (0x0042) + 11 1011 0111 (0x03B7)

ハイ(高位)サロゲートを形成するために上位ビットに0xD800を加える。 00 0100 0010 (0x0042) + 1101 1000 0000 0000 (0xD800) = 1101 1000 0100 0010 (0xD842)
ロー(下位)サロゲートを形成するために下位ビットに0xDC00を加える。 11 1011 0111 (0x03B7) + 1101 1100 0000 0000 (0xDC00) = 1101 1111 1011 0111 (0xDFB7)
結果: D842 DFB7 (UTF-16 符号単位列) D8 42 DF B7(UTF-16BEでの符号化バイト列) 42 D8 B7 DF(UTF-16LEでの符号化バイト列)

次の表は、この文字変換と他をまとめたものである。 色は、コードポイントからのビットがUTF-16バイトにどのように分配されるかを示した。 なお、UTF-16エンコーディングプロセスによって追加された追加ビットは黒で示されている。

文字
(符号位置)
符号位置(2進数) UTF-16
符号単位列(2進数)
UTF-16
符号単位列
UTF-16BE
符号化バイト列
UTF-16LE
符号化バイト列
$ U+0024 0000 0000 0010 0100 0000 0000 0010 0100 0024 00 24 24 00
U+20AC 0010 0000 1010 1100 0010 0000 1010 1100 20AC 20 AC AC 20
𠮷 U+20BB7 0010 0000 1011 1011 0111 1101 1000 0100 0010 1101 1111 1011 0111 D842 DFB7 D8 42 DF B7 42 D8 B7 DF
最大値 U+10FFFF 1 0000 1111 1111 1111 1111 1101 1011 1111 1111 1101 1111 1111 1111 DBFF DFFF DB FF DF FF FF DB FF DF

[編集]

一つの面は6万5536個の符号位置がある。

符号位置 英語での名称 略称 日本語での名称 収録されている主な文字
第0面 U+0000 - U+FFFF Basic Multilingual Plane BMP 基本多言語面 基本的な文字。
第1面 U+10000 - U+1FFFF Supplementary Multilingual Plane SMP 追加多言語面 古代文字や記号・絵文字類など。
第2面 U+20000 - U+2FFFF Supplementary Ideographic Plane SIP 追加漢字面 漢字専用領域。
第3面 U+30000 - U+3FFFF Tertiary Ideographic Plane TIP 第三漢字面 古代漢字や甲骨文字などが収録される予定[11]
第4面 U+40000 - U+4FFFF 未使用(将来どのような目的で使用するのかすら決まっていない)。
第5面 U+50000 - U+5FFFF
第6面 U+60000 - U+6FFFF
第7面 U+70000 - U+7FFFF
第8面 U+80000 - U+8FFFF
第9面 U+90000 - U+9FFFF
第10面 U+A0000 - U+AFFFF
第11面 U+B0000 - U+BFFFF
第12面 U+C0000 - U+CFFFF
第13面 U+D0000 - U+DFFFF
第14面 U+E0000 - U+EFFFF Supplementary Special-purpose Plane SSP 追加特殊用途面 制御コード専用領域。
第15面 U+F0000 - U+FFFFF Private Use Plane PUP 私用面 BMPの U+E000 - U+F8FF の領域の拡張。
第16面 U+100000 - U+10FFFF

日本では2000年にJIS X 0208を拡張する目的でJIS X 0213(いわゆるJIS第3・第4水準)が制定されたが、この際、新たに採用された文字でUnicodeになかったものの一部は、BMPに収録できず、第2面への収録となった(Unicodeが最終的にJIS X 0213への対応を完了したのは2002年である)。このため、JIS X 0213収録文字をUnicodeで完全にサポートするには、追加漢字面をサポートしたOS