0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プログラマのための文字コードガイド:SHIFT_JISからUTF-32、サロゲートペアまで

Posted at

:man_tone1: これは SHIFT_JIS (ゴト
:man_tone1: これは SHIFT_JIS-2004 (ゴト
:man_tone1: これは Windows-31J (ゴト

:person_with_blond_hair_tone1: 全部同じじゃないですか!?

:man_tone1: これだから素人はダメだ!もっとよく見ろ!

文字コードの歴史と特徴

文字コードには様々なエンコード方式があります。
本記事では、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で表現されます:

  1. Unicodeコードポイント: U+20BB7
  2. 高位サロゲート: 0xD842
  3. 低位サロゲート: 0xDFB7

「👍」は次のようにUTF-16で表現されます:

  1. Unicodeコードポイント: U+1F44D
  2. 高位サロゲート: 0xD83D
  3. 低位サロゲート: 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で表現されます:

  1. サムズアップ(U+1F44D)👍

    • 高位サロゲート: 0xD83D
    • 低位サロゲート: 0xDC4D
  2. 中くらいのスキントーン(U+1F3FD)

    • 高位サロゲート: 0xD83C
    • 低位サロゲート: 0xDFFD

したがって、「👍🏽」は以下のように4つの16ビットコードユニットで表現されます:

  1. 高位サロゲート(サムズアップ):0xD83D
  2. 低位サロゲート(サムズアップ):0xDC4D
  3. 高位サロゲート(中くらいのスキントーン):0xD83C
  4. 低位サロゲート(中くらいのスキントーン):0xDFFD

まとめ

本記事では、文字コードの歴史と特徴について紹介しました。
現在では、UTF-8が最も広く使用されていますが、レガシーシステムや特定の環境では他のエンコード方式が依然として使われている感じですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?