Unicode 2.0 (1996) で標準化された 16bit ベース可変長エンコーディング。BMP (Basic Multilingual Plane) は 2 バイト・補助文字 (絵文字・古代文字等) はサロゲートペア (4 バイト) で表現。Windows API/.NET/Java/JavaScript の内部文字列表現として広く利用される。
UTF-16 (UCS Transformation Format - 16bit) は、Unicode 2.0 (1996) で標準化された 16bit ベースの可変長エンコーディングで、BMP (Basic Multilingual Plane、基本多言語面 U+0000-U+FFFF) は 2 バイト・補助文字 (絵文字・古代文字・補助漢字等 U+10000-U+10FFFF) はサロゲートペア (4 バイト) で表現します。元々の Unicode 1.0 (1991) は UCS-2 (固定 2 バイト) で 65,536 字の表現を想定していましたが、絵文字・古代文字・補助漢字の追加で 65,536 字では不足が判明、1996 年の Unicode 2.0 でサロゲートペア機構を導入し UTF-16 として再定義され、Unicode 全範囲 (16 億字、実用上 110 万字) を表現可能になりました。Windows API (Win32)・.NET String・Java String・JavaScript 文字列の内部表現として広く利用され、OS 内部処理での文字列扱いが UTF-16 ベースとなることが多いです。
| エンコーディング | バイト数 | ASCII 互換 | エンディアン | 用途 |
|---|---|---|---|---|
| UTF-8 | 1-4B | 完全 | 不要 | Web/ファイル |
| UTF-16 | 2 or 4B | 不可 | BE/LE | OS 内部 |
| UTF-32 | 4B | 不可 | BE/LE | 処理用 |
| UCS-2 | 2B 固定 | 不可 | BE/LE | UTF-16 の旧版 |
CreateFileW 等の W 系関数String 型、UTF-16 内部表現UTF-16 は OS 内部処理での選好性が高く、Windows API を直接呼ぶ C++ 開発・Java/C# プログラミングで意識する必要があります。Windows ファイル名は内部的に UTF-16 (NTFS の Unicode サポート)、Win32 API の *W 系関数 (例: CreateFileW・ReadFileW) で UTF-16 ワイド文字 (wchar_t*) を受け取ります。Java/C# 開発者は文字列が内部 UTF-16 であることを意識せずに使えますが、サロゲートペアを含む絵文字・古代文字を処理する際に文字数カウントで問題が発生 ("𝕊".length は 2 になる)。JavaScript も同様で、for...of で正しく 1 文字ずつ取得可能。ファイル保存・ネットワーク送信では UTF-16 より UTF-8 が圧倒的に主流、UTF-16 は内部処理用と割り切るのが現代的な使い分けです。
Q1: サロゲートペアとは? A: BMP 外の文字 (絵文字・古代文字) を 4 バイトで表現する機構。高位サロゲート (D800-DBFF) + 低位サロゲート (DC00-DFFF) のペアで、合計 100 万字以上の補助文字を表現可能。
Q2: なぜ Windows API は UTF-16? A: Windows NT 1993 年設計時に Unicode 1.0 (UCS-2 固定 2 バイト) を採用、当時 65,536 字で十分と判断。後にサロゲートペア導入で UTF-16 となった。
Q3: 文字数カウントで問題が出る理由は?
A: 「ABCD😀」の長さを length で取ると JavaScript/Java では 6 になる (絵文字がサロゲートペアで 2 単位)。Array.from(str).length や Unicode aware なライブラリ使用が必要。