One text reading character encoding

文字コードとは何か

コンピュータの世界には 0 と 1 しかないことはよく知られています。文字コードがなければ、私たちが目にするのは「11001010010101100111001....」という数字の羅列です。これでは意思疎通は猫に小判です。私は理解できず、コンピュータも私を理解できません。文字コードは人間と機械の間の翻訳プログラムのようなもので、私たちがよく知る文字を機械が読み取れるバイナリ文字に変換し、バイナリ文字を私たちが理解できる文字に変換します。以下は百科事典による文字コードの説明です

文字コード(キャラクタセットコード)とは、文字セット内の文字を指定された集合(ビットパターン、自然数列、8 ビット群、電圧パルスなど)のオブジェクトにエンコードすることで、テキストをコンピュータに保存したり通信ネットワークを通じて送信したりできるようにする仕組みです。身近な例としては、ラテンアルファベットをモールス符号や ASCII にエンコードすることが挙げられます。たとえば、ASCII コーディングは文字、数字、その他の記号に番号を割り当て、7 ビットのバイナリでその整数を表現します。文字セットは複数の文字の集合です。文字セットには多くの種類があり、各文字セットには異なる文字が含まれています。一般的な文字セット名には、ASCII 文字セット、GB2312 文字セット、Big5 文字セット、GB18030 文字セット、Unicode 文字セットなどがあります。コンピュータがあらゆる種類の文字を正確に処理するには、文字をエンコードしてコンピュータが認識・保存できるようにする必要があります

コンピュータにコーディングが必要な理由

エンコーディングとは、あらかじめ決められた方法を用いて、情報(文字、数字、記号などの文字、画像、音声、その他のオブジェクト)を指定された電圧パルス信号やバイナリ桁に変換するプロセスです。私たちが目にする画像、聴く音楽、書くコードの行、入力する文字は、すべて実在するものです。しかし実際には、その背後には「01」の数字列があります。昨日スマートフォンで見た魅力的な女性は、現実世界に存在するわけではありません。それはコンピュータが「01」という数字で生成した「骨格」に過ぎません

バイナリは存在しない

コンピュータのデータは「01」のバイナリだと思っているかもしれませんが、実際にはコンピュータの中にバイナリは存在しません。すべての内容がハードディスクに保存されていることはわかっていても、分解してみれば「0101」という数字はどこにも見つかりません。あるのはディスクとトラックだけです。ディスクを拡大して見ても、あるのは凹凸のあるディスク表面だけです。凸部は磁化されており、凹部は磁化されていません。しかし、私たちは凸部を「1」、凹部を「0」と名付けたのです

同様に、メモリの中にもバイナリの数字は見つかりません。メモリを拡大すると、それはコンデンサバンクの積み重ねです。メモリセルが「0」を保存しているか「1」を保存しているかは、コンデンサが充電されているかどうかによります。充電されていれば「1」、充電されていなければ「0」とみなします。ただし、コンデンサは長期間のうちに放電します。「1」を表すコンデンサは放電し、「0」を表すコンデンサは充電を引き込みます。これがメモリに通電し続ける必要がある理由です。定期的にコンデンサを充電して、「1」のコンデンサの電力を維持する必要があります

ディスプレイについては、最も直感的に感じられる部分です。ディスプレイを通して見る美しい絵画、日月、山や川は、実際には LED が発する異なる色の光の点です。ディスプレイは LED のグループで構成されるマトリックスであり、各ダイオードをピクセルと呼ぶことができます。「1」は点灯を意味し、「0」は消灯を意味します。通常見えるカラフルな色は、LED の三原色(赤・緑・青)の組み合わせです。では、ASCII コードの「65」はどうやって「A」として表示されるのでしょうか。これはビデオカードの働きによるものです。ビデオカードは各文字のグラフィックデータ(字型コードとも呼ばれます)を保存し、二次元マトリックスのグラフィックデータをディスプレイに送信して成像します

つまり、いわゆる 0 と 1 は電流パルス信号であり、バイナリは私たちが抽象化した数学的論理概念なのです。なぜバイナリ表現を使うのでしょうか

バイナリには 2 つの状態しかないため、バイナリの各ビットを 2 つの安定状態を持つ物理デバイスで表現できます。たとえば、高電圧・低電圧、電荷の正負、ライトの点灯・消灯などの特性で容易に「0」と「1」を表現できます。このことが、コンピュータが論理演算と論理判断を実現する上で有利な条件を提供しています

コンピュータのコード変換プロセス

コンピュータは「01」という論理概念しか表現できないため、画像や文字を直接表現できず、何らかの変換プロセスが必要です

実際には、私たちは特定の規則に従って文字と数値のマッピング関係を維持しています。たとえば、「A」をコンピュータ内で「1」と抽象化し、「1」を見たら「A」と認識します。これは本質的にマッピングテーブルです。理論上は、各文字に任意に固有の文字コードを割り当てることができます。たとえば次のテーブルのように

次に、テキストの入力、トランスコード、保存、出力(表示 / 印刷)の一連の流れを見ていきましょう。まず、コンピュータはアメリカ人が発明したものです。ルールはアメリカ人が設定しました。キーボードのキーはすべて英語文字です。そのため、数字の割り当ても勝手に決められるわけではありません。英語文字の入力には、キーボードと ASCII コードの間に直接的な対応関係があります。キーボードの「A」キーに対応する数字「65」は、ディスクに保存されるバイナリ「01000001」としての「65」の逐語訳でもあります。これは理解しやすいですね

しかし、漢字入力の場合はそうではありません。キーボードには漢字に対応する入力キーがありません。直接漢字を入力することは不可能です。そこで入力コード、内部コード、字型コードの間に変換関係が生じます。入力コードは英語キーボードのキーを漢字に変換し、内部コードは漢字をバイナリシーケンスに変換し、字型コードはバイナリシーケンスをディスプレイに出力して画像化します

入力コード

漢字の入力過程をシミュレートしてみましょう。まず、テキストエディタを開いて「nihao」とローマ字を入力します。すると、入力フィールドに複数の漢字候補が表示されます。最後に対応する番号を選択して漢字を入力します。このプロセスはどうやって実現されるのでしょうか

コンピュータの分野には、モーセの十戒のような格言があります。「コンピュータサイエンスの分野におけるあらゆる問題は、間接的な中間層を追加することで解決できる」

ここで、キーの文字の組み合わせと漢字のマッピングテーブルというもう一つの層を追加します。英中辞書のようなものです。この層を入力コードと呼びます。入力コードから内部コードへのプロセスはルックアップテーブル変換操作です。たとえば ASCII 文字の「nihao」があります。マッピングテーブルと候補番号は自由に修正できます。「你好」にも「小楊你好」にもマッピングできます

内部コード

内部コード(内码)は文字コードの中核部分であり、コンピュータ内で文字セットの実際の保存、交換、通信に使用されるバイナリコードです。内部コードを通じて、テキストの効率的な保存と送信を実現できます。外部コード(入力コード)はキーボードのキーと文字のマッピングと変換を実現しますが、内部コードは文字を機械が読み取れるバイナリ言語に変換します

字型コード

コンピュータ内の文字はすべて内部コードのバイナリ形式で表現されています。では、どうやって数字に対応する文字をディスプレイに表示するのでしょうか。たとえば、数字「1」が漢字の「你」を表すとします。どうやって「1」を「你」として表示するのでしょうか

これは字型コードに依存します。字型コードは本質的に n × n ピクセルのマトリックスです。一部の位置のピクセルを白(1 で表現)に設定し、他の位置のピクセルを黒(0 で表現)に設定します。各文字のフォントはコンピュータに事前に保存されており、このフォント情報ライブラリを字型ライブラリと呼びます

たとえば、漢字の「你」のビットマップは、16 × 16 ピクセルのマトリックスで、32 バイトの領域を必要とします。右側のフォント情報が字型コードと呼ばれます。異なるフォントライブラリ(宋体や太字など)では、同じ文字でも異なる字型コードを持ちます

したがって、文字コードから表示される字型コードへのマッピングは、実質的にもう一つのルックアップテーブル、すなわち文字コードと字型コードの間のマッピングテーブルです

実際、文字コードを字型コードの圧縮方式と捉えることもできます。32 バイトのピクセルマトリックスを 2 バイトの内部コードに圧縮しているのです

文字コードの歴史

電信コード

広義のコーディングは長い歴史を持ち、古代の結縄時代まで遡ることができます。ただし、現代的な文字コードにより近いのはモールス符号の発明であり、これが情報通信時代の幕を開けました。モールス符号は 1837 年にアメリカのモールスによって発明され、ASCII よりも 100 年以上早いものです。初期の無線通信において非常に重要な役割を果たし、すべての無線通信士が知っておくべきものでした。モールス符号は点「.」と線「-」から成ります。電信では短点と長点として表現されます。バイナリと同様にバイナリコードです。1 ビットではアルファベットを表現するには明らかに不十分なため、複数のビットを組み合わせて表現します。たとえば、点線「.-」は文字「A」を表し、線点点「-...」は文字「B」を表します

コーディング時代

コンピュータが最初に発明された頃は、数学計算問題を解くために使われていました。その後、人々はコンピュータがテキスト処理など、もっと多くのことができることを発見しました。当時、機械は非常に大きく、互いに孤立していました。機械同士の通信問題を考慮していなかったため、主要メーカーは各自でハードウェアを作り、ソフトウェアを作り、好きなようにコーディングしていました

その後、機械同士が通信する必要が生じた時、異なるコンピュータで表示される文字が異なることが発覚しました。IBM では数字「00010100」が「A」を表すのに、Microsoft では「B」として表示されたのです。これには誰もが唖然としました。そこで米国国家規格協会 (ANSI) により情報交換用米国標準コード(ASCII)が開発され、ゲームのルールが統一され、どのバイナリ数字でどの共通記号を表現するかが規定されました

百花斉放

英語圏の国々にとって ASCII コード規格の統一は喜ばしいことでしたが、ASCII コーディングは英語文字しか考慮していませんでした。その後、コンピュータがヨーロッパに導入されると、フランス人はアルファベット記号(例:é)を追加する必要があり、ドイツ人はいくつかの文字(Ö ö、Ü ü、Ä、ß)を追加する必要がありました。幸い、ASCII は最初の 127 個の番号しか使用していなかったため、ヨーロッパ諸国は未使用の ASCII コード(128〜255)を独自の記号コードとして利用し、うまく共存できました

しかし、中国に導入されると、奥深い中国語は完全に行き詰まりました。何万もの漢字があり、255 個の数字では全く足りません。そこで後にマルチバイトコードが登場します。そのため、各国がそれぞれの言語コードテーブルを導入し、後の ISO 8859 シリーズ、GB シリーズ(GB2312、GBK、GB18030、GB13000)、Big5、EUC-KR、JIS などが生まれました。ただし、コンピュータシステムで汎用性を持たせるため、これらの拡張コードは直接的または間接的に ASCII コードと互換性があります

Microsoft / IBM などの国際メーカーは製品を世界中で販売するため、各国の言語をサポートする必要があり、各地域でローカルのコーディング方式を採用しました。そのため、世界中のすべてのコーディング方式を集めて番号を振り、コードページ(内部コードテーブルとも呼ばれます)と呼びました。そのため、xx コードページという表現で特定の文字コードを指すことがあります。たとえば、Microsoft のシステムでは、中国語 GBK コードはコードページ 936 に、繁体字中国語 Big5 コードはコードページ 950 に対応します

ASCII と互換性があるものの互いに互換性のないこれらの文字コードは、後に ANSI コードと総称されるようになりました。次の図に見覚えがある方も多いでしょう。Windows では、基本的に ANSI コードを使用して保存しています

ANSI の文字通りの意味は文字コードではなく、米国国家規格協会の略称である非営利団体を指します。ANSI は文字コードの規格開発に多くの貢献をしてきました。後に、人々はこのようなマルチバイトエンコーディングを ANSI エンコーディングまたは標準コードページと呼ぶようになりました

ANSI コードは一つのモデルに過ぎず、システムのデフォルトエンコーディング方式を大まかに表すものであり、特定のコーディング方式を指すものではありません。たとえば、Windows オペレーティングシステムでは、中国の ANSI コードは GB コードを指し、香港の ANSI コードは Big5 コードを指し、韓国の ANSI コードは EUC-KR コードを指します

世界の統一

各国が独自の文字コードを持っているため、ある人が中国語のテキストに韓国語を 2 行挟みたい場合はどうなるのでしょうか。残念ながら、そのレベルは高すぎてサポートされません。GB2312 を選択している限り、漢字しか入力できません。同時に、主要な国際メーカーも様々な文字コードの互換性の問題に悩まされ、ついに世界のすべての文字を収容できる統一コードの開発を決意しました。こうして登場したのが有名な Unicode です

Unicode はユニバーサルコードとも呼ばれ、文字セット、コーディングスキームなどを含みます。Unicode は従来の文字コード方式の制限を解決するために作られました。各言語の各文字に統一された固有のバイナリコードを設定することで、この言語環境では言語コードの衝突がなくなり、あらゆる国の言語のコンテンツを同じ画面に表示できます。これが Unicode の最大の利点です

Unicode エンコーディング方式には、UTF-7、UTF-8、UTF-16、UTF-32 の 4 つの一般的な実装があります。最もよく知られているのは UTF-8 です。ただし、Unicode の設計当初はダブルバイト固定長エンコーディングの UTF-16 が採用されましたが、歴史的な負担が重すぎて普及しにくいことが判明しました。最終的にはより長い UTF-8 が広く受け入れられました

文字コードモデル

従来のコーディングモデル

従来の文字コードモデルでは、文字セット内の文字に基本的に 10 進数で 1 つずつ番号を振り、その 10 進数を直接対応するバイナリコードに変換します。つまり、文字番号がそのまま文字コードなのです

実際、コンピュータは文字と数値の変換関係を処理する際、マッピングテーブルを参照するプロセスです。たとえば、ASCII エンコーディングは各英語文字に固有の番号を割り当てます。エンコーディングプロセス全体は比較的シンプルで、コンピュータは直接バイナリにマッピングし、10 進数は私たちの便宜上使用されているだけです

現代的コーディングモデル

Unicode コーディングモデルは新しいコーディング概念を採用しており、コーディングモデルを 4 つのレイヤー(または 5 つのレイヤー)に分割しています。ただし、第 5 レイヤーはトランスポート層のコーディング適応であり、厳密にはコーディングモデルには含まれません

- 第 1 レイヤー、Abstract Character Repertoire (ACR):抽象文字セットを定義し、各抽象文字を定義します

- 第 2 レイヤー、Coded Character Set (CCS):抽象文字セットに番号を割り当てます

- 第 3 レイヤー、Character Encoding Form (CEF):文字番号を論理コードシーケンスにエンコードします

- 第 4 レイヤー、Character Encoding Scheme (CES):論理シンボルシーケンスを物理バイトシーケンスにエンコードします

第 1 レイヤー:抽象文字セット ACR

いわゆる抽象文字セットは抽象文字の集合であり、順序付けされていないセットです。ここで強調すべきは、文字が抽象的であるということです。つまり、目に見える有形の文字(「a」など)だけでなく、目に見えない制御文字(「DELETE」や「NULL」など)も含みます

抽象的であることのもう一つの意味は、いくつかの字形が複数の文字で構成されていることです。たとえば、スペイン語の「ñ」は「n」と「~」の 2 文字で構成されています。この点で、Unicode は従来のコーディング規格とは異なり、従来の規格は「ñ」を独立した文字とみなすことが多いのに対し、Unicode はそれを 2 文字の組み合わせとみなします

同時に、1 つの文字が複数の視覚的フォント表現を持つこともあります。たとえば、漢字には楷書、行書、草書、隷書など多くの書体がありますが、これらはすべて同じ抽象文字とみなされます(つまり、文字セットのコーディングはフォントではなく文字をエンコードするため、表示方法はフォントライブラリに依存します)

抽象文字セットはオープンまたはクローズドのいずれかです。オープンな文字セットは文字を追加し続ける文字セットを指し、クローズドな文字セットは文字を追加しない文字セットを指します。たとえば、ASCII はクローズドで、128 文字のみであり、将来追加されることはありません。しかし、Unicode はオープンで、新しい文字が継続的に追加されています。当初の 7,163 文字から現在では 144,697 文字以上に増加しました

第 2 レイヤー:番号付き文字セット CCS

番号付き文字セットは、抽象文字セット内の各文字に番号を付け、非負整数のセットにマッピングするものです

番号は通常、人間が読みやすい 10 進数または 16 進数で表現されます。たとえば、「A」の文字番号は「65」、「B」の文字番号は「66」です

注意すべきは、一部の文字エンコーディングでは番号がそのまま保存バイナリシーケンスになることです。ASCII エンコーディングがその例です。一方、GB2312 や Unicode などの文字コードでは、番号と保存バイナリシーケンスが異なります

さらに、番号付き文字セットの範囲は制限されています。たとえば、ASCII 文字セットの範囲は 0〜127、ISO-8859-1 の範囲は 0〜256 です。GB2312 は 94 × 94 の二次元テーブル空間で表現されます。Unicode は Plane 空間の概念で表現され、これを文字セットの番号空間と呼びます

番号空間内の位置を符号位置(コードポイント)と呼びます。文字が占める符号位置の座標(非負整数値のペア)、またはそれが表す非負整数値がその文字の符号値(コードポイント番号)です

第 3 レイヤー:文字エンコーディング形式 CEF

抽象文字セットと番号付き文字セットは私たちの理解を容易にする視点から見たものです。最終的にはコンピュータが理解できる言語に変換し、10 進数をバイナリ形式に変換する必要があります

したがって、文字エンコーディング形式は文字セットの符号位置番号をバイナリコードユニットシーケンスに変換するプロセスです

符号単位:文字エンコーディングの最小処理単位です。たとえば、ASCII の 1 文字は 1 バイトに等しく、シングルバイト符号単位に属します。UTF-16 の 1 文字は 2 バイトに等しく、処理は「ワード」単位で行われるため、ダブルバイト符号単位です。UTF-8 はマルチバイトエンコーディングで、シングルバイト文字とマルチバイト文字を含み、各処理はシングルバイト単位で行われるため、最小処理単位はバイトであり、これもシングルバイト符号単位です

ここで疑問が生じるかもしれません。なぜこのレイヤーを独立して抽出する必要があるのでしょうか

初期の文字エンコーディングもこのように処理されていました。10 進数とバイナリを直接変換していました。たとえば ASCII コード。文字「A」の 10 進数は「65」で、対応するバイナリは「1000000」です。同時に、このバイナリがそのままハードディスクに保存されていました。当時のエンコーディングは比較的シンプルでした

MBCS(マルチバイト文字セット)の登場により、文字番号とバイナリは直接変換されなくなりました。たとえば GB2312 コード。「万」の位置番号は「45, 82」で、対応するバイナリ内部コードは「1100 1101 1111 0010」(10 進数では「205242」)です

変換せずに直接バイナリコードにマッピングしたらどうなるでしょうか。「万」の文字番号は「45, 82」です。45 は ASCII で「-」、82 は「U」です。「-U」の 2 文字を表示すべきか、1 文字の「万」を表示すべきか。この競合を避けるためにプレフィックス処理が追加されます。詳細なプロセスは後述します

第 4 レイヤー:文字エンコーディングスキーム CES

文字エンコーディングスキームは「シリアル化形式」とも呼ばれ、文字番号をエンコードした後のコード要素シーケンスをバイトシーケンス(バイトストリーム)の形式にマッピングすることを指します。これにより、エンコードされた文字をコンピュータで処理、保存、送信できます

文字エンコーディング形式 CEF はデータベース構造設計における論理設計のようなもので、このレイヤーのエンコーディングスキーム CES は物理設計のようなものです。コードシーケンスを特定のコンピュータシステムプラットフォームに関連する物理的なバイナリプロセスにマッピングします

ここで、なぜバイナリシンボルシーケンスと実際に保存されるバイナリが異なるのかと疑問に思うかもしれません。これは主にコンピュータのビッグエンディアンとリトルエンディアンの問題によるものです。具体的なエンディアンについては UTF-16 コーディングのセクションで詳しく説明します

ビッグエンディアンとリトルエンディアンの用語はジョナサン・スウィフトの『ガリヴァー旅行記』に由来します

誰もが卵の大きい端を割って食べるのが本来の方法だと信じていました。しかし、皇帝の祖父が幼い頃、昔ながらの方法で卵を割ろうとして指を怪我しました。そのため、父親である当時の皇帝は勅令を出し、すべての臣民に卵を食べる時は小さい端を割るよう命じ、違反者には厳しい罰を科しました。民衆はこの命令に強い反感を抱きました。歴史によれば、6 回の反乱があり、そのうち 1 回は皇帝が命を落とし、もう 1 回は王位を失いました。この論争について何百もの大著が出版されましたが、ビッグエンディアン学派の書物は常に発禁処分を受け、法律でもその学派の者は公務員になれないと定められています

一般的な文字コード

ASCII

昔々、コンピュータメーカーはそれぞれ独自の方法で文字を画面に表示していました。当時のコンピュータは家ほどの大きさで、誰もが手を出せるものではありませんでした。当時、人々はコンピュータ間の通信方法について気にしていませんでした。1970 年代から 1980 年代にかけてマイクロプロセッサが登場すると、コンピュータはますます小型化し、パーソナルコンピュータが一般に普及し始め、爆発的な発展が続きました。しかし、それまで各メーカーは独自に開発を進め、自社製品が他社製品と互換性を持つべきだと考えていなかったため、異なるコンピュータシステム間のデータ変換が非常に困難でした。そこで米国規格協会は 1967 年に ASCII コードを策定し、これまでで 128 文字を定義しています

最初の 32 個(0〜31)は不可視の制御文字、32〜126 は可視文字、127 は削除コマンド(キーボードの DEL キー)です

実は、ASCII より前の 1963 年に、IBM は EBCDIC という文字エンコーディングシステムを導入していました。ASCII コードと同様に、制御文字、数字、一般的な句読点、大文字と小文字の英語文字を含んでいます

ただし、EBCDIC の文字番号は連続していなかったため、後のプログラム処理に支障をきたしました。後に ASCII コードは EBCDIC の教訓を活かし、英語文字に連続したコードを割り当ててプログラム処理を容易にしたため、広く受け入れられました

ASCII は EBCDIC コーディングと比較して、文字の連続配置に加えて、バイトの低位 7 ビットのみを使用し、最上位ビットは常に 0 です。この最上位ビットの 0 を過小評価しないでください。一見些細に見えますが、これが ASCII 設計の最も成功した側面です。後にコーディング原則を説明する際にわかりますが、この最上位ビットの 0 により、他のエンコーディング規格が ASCII コードとシームレスに互換できるようになり、ASCII が広く受け入れられることになったのです

ISO-8859 シリーズ

アメリカ市場で文字コードが統一されたものの、コンピュータメーカーはヨーロッパ市場に進出する際に困難に直面しました。ヨーロッパの主要言語もラテンアルファベットを使用していますが、フランス語の「é」やノルウェー語の「ν」など多くの拡張があり、これらは ASCII では表現できません。しかし、ASCII の 128 以降はまだ使用されておらず、ヨーロッパの主要言語には十分でした

そこで登場したのがよく知られた ISO-8859-1(Latin-1)です。ASCII の後半 128 文字を拡張したもので、単一バイトエンコーディングに属します。同時に、元の ASCII コードとの互換性を保つため、最上位ビットが 0 の場合は元の ASCII 文字を維持し、最上位ビットが 1 の場合は拡張ヨーロッパ文字を示します

しかし、これで終わりではありません。前述したのはヨーロッパの主要言語についてですが、フランス語の主流言語には œ、Œ、Ÿ の 3 文字がなく、フィンランド語には Š、š、Ž、ž がありません。単一バイトコードの 256 個の符号位置は使い切られたため、ISO-8859-2 / 3 / ... / 16 シリーズのバリエーションが登場しました。これらはすべて ASCII と互換性がありますが、互いに完全に互換ではありません

ISO-8859-n シリーズの文字セットは以下の通りです

ISO8859-1 文字セット(Latin-1)は西ヨーロッパの常用文字で、ドイツ語やフランス語の文字を含みます。ISO8859-2 文字セット(Latin-2)は東ヨーロッパの文字を収集します。ISO8859-3 文字セット(Latin-3)は南ヨーロッパの文字を収集します。ISO8859-4 文字セット(Latin-4)は北欧の文字を収集します。ISO8859-5 文字セット(Cyrillic)はスラブ語の文字を収集します。ISO8859-6 文字セット(Arabic)はアラビア語の文字を収集します。ISO8859-7 文字セット(Greek)はギリシャ語の文字を収集します

GB シリーズ

コンピュータが東アジア諸国に導入された時、製造業者はさらに驚きました。アメリカやヨーロッパの言語は基本的に表音文字で、1 バイトで十分です。しかし、多くのアジア諸国は表意文字を使用しており、文字数は数万に上ることが多く、1 バイトでは足りません。そこで、中国の関連部門は ISO 規格に基づいて GB2312 ダブルバイトコードを設計しました。ただし、GB2312 はクローズドな文字セットで、常用漢字のみを含み、合計 7,000 文字強です。そのため、より多くの漢字(希少文字を含む)を収容するために、その後 GBK、GB18030、GB13000 が登場しました(「GB」は「国家標準」の中国語拼音の略称の頭文字です)

GB シリーズエンコーディング方式によれば、テキスト内のバイトが 0〜127 であれば、そのバイトの意味は ASCII エンコーディングと同じです。そうでない場合は、そのバイトと次のバイトが一緒になって 1 つの漢字(または GB コードで定義されたその他の文字)を形成します。したがって、GB シリーズはすべて ASCII エンコーディングを含んでいます

GB2312

GB2312 は 2 バイトを使用して漢字を表現するコーディング規格で、6,763 個の漢字と 682 個の非漢字グラフィック文字を含んでいます。ASCII 文字コード(0〜127)との競合を避けるため、漢字を表現するコード化バイトの値は 127 より大きくなければならない(つまり、バイトの最上位ビットが 1)と規定されており、127 を超える 2 つのバイトが連続して初めて 1 つの漢字を表現します(GB2312 はダブルバイトコーディング)。したがって、GB2312 は可変長エンコーディングに属します。英語文字の場合は 1 バイトを占有し、漢字の場合は 2 バイトを占有します。GB2312 は ASCII の中国語拡張と見なすことができます

GB2312 文字セット番号空間は 94 × 94 の二次元テーブルです。行が区(上位バイト)を表し、列が点(下位バイト)を表します。各区には 94 点があり、各区点は 1 つの文字に対応し、区点コードと呼ばれます。区点コードに 2020H を加えると国標コードが得られ、国標コードに 8080H を加えるとコンピュータの内部コードが得られます。ここで区点コード、国標コード、内部コードの概念が導入されます。この 3 つの関係について説明します

国標コード

国標コードは中国の漢字情報交換用標準コードで、4 桁の 16 進数で構成され、2 つの下位 7 ビットバイトで表現されます。ASCII 文字の最初の 32 個の制御コマンド文字との競合を避けるため、各バイトは 33 番目の数字から始まります(下図参照)

区点コード

上記の国標コードの 16 進数コード区は使用時に直感的でないため、10 進数の 94 × 94 二次元テーブル番号空間にマッピングしたものを区点コードと呼びます。同時に、区点コードは外部コードとしても使用できます。入力方式を区点コードに直接切り替えて漢字入力に使用できますが、この入力方式は規則性がなく、区点コードを覚えるのは難しいため、使用者は少ないです

下図は区点コードの二次元テーブルを示しています。たとえば、「万」という文字は 45 区 82 点なので、「万」の区点コードは「45, 82」です

内訳は以下の通りです:- 01〜09 区(682 個):特殊記号、数字、英語文字、タブ文字などで、ラテン文字、ギリシャ文字、日本の平仮名・片仮名、ロシアのキリル文字などを含む 682 個の全角文字

- 10〜15 区:空領域、拡張用に予約

- 16〜55 区(3,755 個):常用漢字(一級漢字とも呼ばれる)、拼音順に並べ替え

- 56〜87 区(3,008 個):非常用漢字(二級漢字とも呼ばれる)、部首・画数順に並べ替え

- 88〜94 区:空領域、拡張用に予約

内部コード

GB2312 の国標コード仕様は、ASCII の可視部分の記号と英語文字をカバーしており、2 つの 7 ビットコードを使用してその中の英語文字と記号を再プログラムします。ただし、これには欠点があります。ASCII でエンコードされた初期の英語記事は開けなくなります。開くと文字化けしてしまうのです。つまり、初期の ASCII コードと互換性を保つ必要があり、上書きしてはいけなかったのです。後に Microsoft はバイトの最上位ビットを 1 に設定することでこの問題を解決しました。ASCII は 7 ビットを使用し最上位ビットが 0 であるため、変換されたコードは内部コード(内码)と呼ばれます。これは本質的に GB2312 のコーディング規格を修正したもので、最終的に広く受け入れられました

3 つの変換関係をまとめます:区点コード → 区コードと点コードにそれぞれ 32(すなわち +20H)を加えて国標コードを得る → それぞれ 128(すなわち +80H)を加えて内部コードを得る(ASCII コードとの競合なし)

GBK

GBK は「国家標準拡張」を意味します。GB2312 のダブルバイトでは最上位ビットが 1 より大きい必要があるため、上限は 1 万文字を超えません。この拡張では GB2312 の文字を再エンコードせずに直接利用するため、GB2312 と完全に互換性があります。GBK もダブルバイトエンコーディングですが、最初のバイトが 127 より大きいことだけを要求し、これが漢字の始まりであることを示します。このため、GBK のエンコーディングスペースは GB2312 よりもはるかに大きくなります

GBK の全体的なエンコーディング範囲は 8140 〜 FEFE です。最初のバイトは 81 〜 FE、最後のバイトは 40 〜 FE の間です。xx7F を除外すると、合計 23,940 個のコードビットがあり、21,886 個の漢字とグラフィックシンボルを含みます。その中で、GBK/1 は GB 2312 文字以外の補足文字を含み、GBK/2 は GB2312 文字を含み、GBK/3 は CJK 文字を含み、GBK/4 は CJK 文字と補足文字を含み、GBK/5 は非漢字で、UDC はユーザー定義文字です

詳細は以下の通りです

ここで 2 つの疑問が生じるかもしれません。なぜ終端バイトは 00 からではなく 40 から始まるのか。なぜ FF と xx7F の番号を除外するのか

GBK の終端バイトエンコーディングでは上位ビットが 1 という必須要件はありません。上位ビットが 0 の場合、ASCII コードと競合します。ASCII の 00 〜 40 の間の文字のほとんどは制御文字であるため、制御文字を除外するのは、主に上位バイトの損失が深刻なシステム結果を引き起こすのを防ぐためです

FF は GB2312 との互換性を保つために除外されます。GB2312 の点コードは予約されています。7F は DEL 文字が後方に削除されることを意味し、送信中に最初のバイトが失われると深刻な結果が発生するため、xx7F も除外する必要があります。これはすべてのコーディング方式が注意すべき点です

GB18030

コンピュータの発展に伴い、GBK の 2 万文字超では依然として不十分であったため、2000 年に中国は新しい規格 GB18030 を制定して GBK を代替しました。GB18030 は強制規格です。現在、中国本土で販売されるすべてのソフトウェアは GB18030 をサポートしています

GB18030 は実質的に Unicode に整合した規格であり、すべての Unicode 文字セットを含み、Unicode の実装(UTF)の一種でもあります

では、なぜ独自の UTF 実装を構築する必要があるのでしょうか

UTF-8 / UCS-2 は GB2312 と互換性がありません。直接アップグレードすると、コードは完全に文字化けしてしまいます。そのため、GB18030 は GBK と GB2312 のスーパーセットです。元の GB2312(GBK)ソフトウェアから国際的な Unicode へのアップグレードを検討する場合、GB18030 を直接使用してアップグレードできます

GB18030 も GB2312 の拡張ですが、GBK とは拡張モードが異なります。GBK は主に GB2312 の未定義エンコーディングスペースを活用するのに対し、GB18030 はバイト可変長エンコーディングを使用し、シングルバイト領域は ASCII と互換、ダブルバイト領域は GBK と互換、4 バイト領域はすべての Unicode 符号位置に整合しています

原理上、2 番目のバイトで使用されていない 0x30 〜 0x39 のエンコーディングスペースを利用して、4 バイトが必要かどうかを判断します

Related Articles

Explore More Special Offers

  1. Short Message Service(SMS) & Mail Service

    50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00

phone お問い合わせ
Hi, I'm Alibaba Cloud AI Assistant!
I can help with questions and solutions.