これは SHIFT_JIS (ゴト
これは SHIFT_JIS-2004 (ゴト
これは Windows-31J (ゴト
全部同じじゃないですか!?
これだから素人はダメだ!もっとよく見ろ!
文字コードの歴史と特徴
文字コードには様々なエンコード方式があります。
本記事では、SHIFT_JIS、SJIS、Windows-31J、cp932、EUC-JP、UTF-8、UTF-16、UTF-32について、それぞれの歴史と特徴を紹介します。
また、サロゲートペアと絵文字についても触れます。
SHIFT_JIS (SJIS)
※Rubyでは SHIFT_JIS ≠ SJIS なので注意。(1.9.3以降SJISはWindows-31Jのエイリアスになっています)
歴史
SHIFT_JISは、1980年代に日本のパソコンで広く使われるようになった文字コードで、ASCII、JIS X 0201およびJIS X 0208を基にして開発されました。
特徴
- 1バイトと2バイトの組み合わせ: ASCII文字は1バイトで表現され、日本語の漢字やかなは2バイトで表現されます
- 広い互換性: 当時の日本のパソコンや携帯電話で広く使用されました
- エンコード範囲: 2バイトコードの範囲が広く、誤ったバイトシーケンスが発生しやすいため、データの整合性に注意が必要です。また、Shift_JISは互換性が高いものの、エンコードの範囲が広いためバイトシーケンスの解釈が難しい場合がある
SHIFT_JIS-2004
歴史
SHIFT_JIS-2004は、2004年に改訂されたShift_JISのバージョンで、JIS X 0213:2004規格に基づいています。JIS X 0213は、従来のJIS X 0208にない新しい文字や記号を追加した規格です。
特徴
- JIS X 0213のサポート: 従来のJIS X 0208に加え、JIS X 0213で定義された追加文字をサポートします
- 互換性の保持: 基本的には従来のShift_JISとの互換性を保持しつつ、新しい文字セットを取り入れています
- エンコードの拡張: さらに多くの文字や記号をエンコードできるようになり、日本語の表現力が向上しました
Windows-31J (cp932)
歴史
Windows-31Jは、マイクロソフトによってSHIFT_JISを拡張した文字コードで、Windows環境で広く使用され、CP932とも呼ばれます。
特徴
- 互換性の拡張: SHIFT_JISに独自の拡張を加え、IBM拡張文字も含んでいます
- Windows依存: 主にWindows環境で使用され、他のプラットフォームでは互換性の問題が生じる場合がある
EUC-JP
歴史
EUC-JPは、UnixおよびLinux環境で広く使用される文字コードで、1980年代に登場しました。JIS X 0208とJIS X 0201を基にしています。
Solarisで使った記憶があります。
特徴
- エンコードの簡便さ: 最上位ビットを使用することで、文字の種類(1バイト、2バイト)を判別しやすい
- 互換性: Unix系システムでの日本語処理には適していましたが、現在ではUTF-8が標準で使用されています
UTF-8
歴史
UTF-8は1990年代に開発され、今日最も広く使用されているUnicodeエンコーディング形式です。ISO 10646とUnicodeを基にしています。
特徴
- 可変長エンコード: 1バイトから4バイトの可変長エンコードを使用します
- 互換性: UTF-8はASCIIとの互換性があり、英数字を含む多くのテキストで効率的に扱えます
- グローバル標準: インターネットや様々なアプリケーションで標準的に使用されています。特にウェブページやメールのエンコーディングとして広く採用されています
UTF-16
歴史
UTF-16は、1990年代にUnicodeの一部として開発されました。主にWindows、Javaプラットフォーム、および一部のデータベースシステムで使用されています。
特徴
- 固定長と可変長: 基本的には2バイトでエンコードされますが、基本多言語面(BMP)外の文字を表現する際にはサロゲートペアを使用することで4バイトになります
- 広範な文字サポート: Unicodeの広範な文字セットをサポートします
UTF-32
歴史
UTF-32も1990年代にUnicodeの一部として開発されました。全ての文字を固定長の4バイトでエンコードします。
特徴
- 固定長エンコード: 全ての文字が4バイトで表現されるため、文字の長さが一定で管理が容易です
- メモリ消費: 全ての文字が固定長の4バイトで表現されるため、大量のメモリを消費し、特にメモリ効率が重要なアプリケーションには適さないことがあります
サロゲートペア (Surrogate Pair)
概要
サロゲートペアは、UTF-16で基本多言語面(BMP)外の文字を表現するための仕組みです。
2つの16ビットコードユニットで1つのUTF-16文字を表現します。
特徴
- 高位サロゲート: 上位ビットが110110から始まる16ビット値。(0xD800から0xDBFFまで)
- 低位サロゲート: 上位ビットが110111から始まる16ビット値。(0xDC00から0xDFFFまで)
具体的には、「𠮷」は次のようにUTF-16で表現されます:
- Unicodeコードポイント: U+20BB7
- 高位サロゲート: 0xD842
- 低位サロゲート: 0xDFB7
「👍」は次のようにUTF-16で表現されます:
- Unicodeコードポイント: U+1F44D
- 高位サロゲート: 0xD83D
- 低位サロゲート: 0xDC4D
プログラミング言語での対応
各プログラミング言語では、サロゲートペアの扱い方が異なります。以下にいくつかの例を示します。
サロゲートペアに対応していない場合、2文字としてカウントしてしまったりといった不具合が生じます。
-
Java:
char
型は16ビットのUTF-16コード単位を表すため、1文字が2つのchar
値に分かれる場合があります。これに対応するために、String
クラスはサロゲートペアを適切に処理し、codePointAt()
やcodePointCount()
などのメソッドを提供しています -
C#:
char
型は16ビットのUTF-16コード単位を表します。string
型はサロゲートペアを適切に処理し、System.Globalization.StringInfo
クラスは文字列内のサロゲートペアを考慮したメソッドを提供しています -
JavaScript:
文字列は内部的にUTF-16で表現されます。サロゲートペアは2つのコード単位として扱われますが、String.prototype.charAt()
やString.prototype.charCodeAt()
などの一部のメソッドはサロゲートペアを適切に処理しません。代わりに、String.prototype.codePointAt()
やfor...of
ループを使用することが推奨されます -
Python:
文字列はUnicodeとして扱われ、サロゲートペアは単一の文字として適切に処理されます。len()
関数は文字数を返し、for
ループは文字列内の各文字を反復処理します。 -
Ruby:
文字列はUTF-8でエンコードされますが、文字列操作はサロゲートペアを適切に処理します。String#length
メソッドは文字数を返し、String#each_char
メソッドは文字列内の各文字を反復処理します -
PHP:
PHPの内部文字列処理はバイト列として扱われ、特にマルチバイト文字やサロゲートペアの処理にはmbstring
モジュールの使用が推奨されます。mb_strlen()
関数やmb_substr()
関数がサロゲートペアを適切に処理します -
Rust:
Rustでは文字列は内部的にUTF-8でエンコードされます。char
型はUnicodeのスカラー値を表し、サロゲートペアはchar
型では表現されません。文字列操作はサロゲートペアを適切に処理します。例えば、String::chars()
メソッドは文字列をUnicodeのスカラー値のイテレータに変換し、サロゲートペアを単一のchar
値として扱います。ただし、String::len()
メソッドはバイト数を返すため、サロゲートペアを含む文字列の文字数を数える場合はString::chars().count()
を使う必要があります。
絵文字 (Emoji)
概要
絵文字は、表情を表したり、物を表したりする文字です。1999年に日本の携帯電話で登場し発展しました。
2010年にUnicode 6.0で正式に採用されました。
特徴
- サロゲートペア: 多くの絵文字はサロゲートペアを使用してUTF-16で表現されます
絵文字のサロゲートペア
例えば、「👍🏽」という絵文字(サムズアップ👍 + 中くらいのスキントーン)は、次のようにUTF-16で表現されます:
-
サムズアップ(U+1F44D)👍
- 高位サロゲート: 0xD83D
- 低位サロゲート: 0xDC4D
-
中くらいのスキントーン(U+1F3FD)
- 高位サロゲート: 0xD83C
- 低位サロゲート: 0xDFFD
したがって、「👍🏽」は以下のように4つの16ビットコードユニットで表現されます:
- 高位サロゲート(サムズアップ):0xD83D
- 低位サロゲート(サムズアップ):0xDC4D
- 高位サロゲート(中くらいのスキントーン):0xD83C
- 低位サロゲート(中くらいのスキントーン):0xDFFD
まとめ
本記事では、文字コードの歴史と特徴について紹介しました。
現在では、UTF-8が最も広く使用されていますが、レガシーシステムや特定の環境では他のエンコード方式が依然として使われている感じですね。