可変長エンコーディング
文字によって使用するバイト数が異なる符号化方式。UTF-8 (1〜4 バイト) や Shift_JIS (1〜2 バイト) が代表例で、頻出文字を短いバイト列で表現することで効率を高める。
可変長エンコーディング (variable-length encoding) は、すべての文字を同じバイト数で表現するのではなく、文字ごとに異なるバイト数を割り当てる符号化方式です。対義語は固定長エンコーディングで、UTF-32 (すべての文字が 4 バイト) や ASCII (すべて 1 バイト) がこれに該当します。
可変長エンコーディングの最大の利点は空間効率です。UTF-8 では ASCII 文字 (英数字、記号) を 1 バイトで表現し、日本語の漢字やひらがなは 3 バイト、一部の絵文字は 4 バイトで表現します。英語テキストが大半を占めるウェブでは、UTF-32 と比較してデータ量を 75% 削減できます。日本語テキストでも、UTF-32 の 4 バイト/文字に対して UTF-8 は 3 バイト/文字で済むため、25% の節約になります。
UTF-8 の可変長設計は巧妙です。先頭バイトのビットパターンを見るだけで、その文字が何バイトで構成されているかが分かります。1 バイト文字は 0xxxxxxx、2 バイト文字は 110xxxxx 10xxxxxx、3 バイト文字は 1110xxxx 10xxxxxx 10xxxxxx、4 バイト文字は 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx です。この自己同期性により、バイト列の途中から読み始めても文字の境界を正しく検出できます。
Shift_JIS も可変長エンコーディングです。ASCII 互換の文字と半角カタカナは 1 バイト、漢字やひらがなは 2 バイトで表現します。ただし Shift_JIS には UTF-8 のような自己同期性がなく、バイト列の途中から読み始めると 1 バイト目と 2 バイト目を取り違える可能性があります。この設計上の弱点が、Shift_JIS でのテキスト処理を複雑にしています。
可変長エンコーディングの最大の落とし穴は、「文字数」と「バイト数」が一致しないことです。UTF-8 で「Hello」は 5 バイト (5 文字)、「こんにちは」は 15 バイト (5 文字) です。文字列の n 番目の文字にアクセスするには、先頭から順にバイト数を数える必要があり、固定長エンコーディングのように単純な掛け算ではアクセスできません。これがプログラミング言語の文字列操作のパフォーマンスに影響します。
データベースやファイルシステムの容量設計では、可変長エンコーディングの特性を正しく理解する必要があります。MySQL の VARCHAR(255) は UTF-8 (utf8mb4) の場合、最大 255 文字ですが、最大バイト数は 1,020 バイト (255 × 4) になります。ストレージの見積もりでは、文字数ではなくバイト数で計算しなければ実態と乖離します。