基本情報の文字コードを解説!ASCII・Unicode・UTF-8の違い

文字コードを学ぶためのノートとパソコン、木のタイルとガラスの立方体

基本情報の文字コードは、「文字に付ける番号」と「その番号を保存・通信する方法」を分けると理解しやすくなります。ASCIIは英数字などの対応を定める規格、Unicodeは多様な文字にコードポイントを割り当てる規格、UTF-8はUnicodeの文字をバイト列へ符号化する方式です。

UTF-8では「A」は1バイト、「あ」は3バイト、「😀」は4バイトです。どれも画面では一つの文字に見えますが、データ量は同じではありません。さらに、見た目が一つでも複数のコードポイントから成る文字があります。

この記事では、三つの用語の違いを整理し、実際のバイト列、文字数とバイト数の計算、文字化けの原因まで説明します。「Unicodeなら必ず2バイト」「半角なら必ず1バイト」と覚えてしまう前に、数える対象を確認していきましょう。

この記事のポイント
  • ASCII・Unicode・UTF-8を役割で区別できる
  • コードポイントと保存されたバイト列を読み分けられる
  • 英数字・日本語・絵文字が混じるデータ量を計算できる
  • 改行・BOM・結合文字による計算の違いを確認できる
無料

基本情報技術者試験 過去問アプリ

本番形式で繰り返し解ける。スキマ時間に1問から

2,000問以上収録
無料で過去問を解く
目次

基本情報の文字コードの違い

色の札を付けた木製の鳥・立方体・球と、容器に並べた同じ形の木製品
文字の識別と保存方法を分けて考えるためのイメージ

文字・番号・バイト列を分ける

コンピュータへ文字を保存するときは、見た目の形をそのまま箱に入れるわけではありません。扱う文字を識別し、取り決めに従って数値やバイト列で表します。読む側も同じ取り決めを使って、保存されたデータを文字として解釈します。

ここでは「文字 → コードポイント → UTF-8のバイト列 → 文字として表示」という順序を考えます。文字が「あ」ならコードポイントはU+3042で、UTF-8のバイト列はE3 81 82です。U+3042とE3 81 82は同じ役割の表記ではありません。

たとえば荷物に付けた管理番号と、運ぶための梱包方法は別のものですよね。コードポイントは文字の識別番号に、符号化は保存・通信できる形への変換に相当すると考えると整理できます。ただし、これは理解のためのたとえで、Unicodeには文字の属性など番号以外の規定もあります。

フォントはさらに別の役割です。同じ文字を丸い書体や細い書体で描くのは表示の処理であり、フォントが違うだけでUTF-8のバイト数が変わるわけではありません。文字コードの問題では、まず表示の形と保存形式を切り分けるのが出発点です。

用語主な役割基本情報での着目点
ASCII英字・数字・記号・制御文字と値の対応を定める7ビットで128種類、通常のバイト保存では1バイト
Unicode多様な文字にコードポイントを割り当てる文字の番号だけから保存バイト数を決めない
UTF-8Unicodeを8ビット単位で符号化する1コードポイントを1〜4バイトで表す

ASCIIは7ビットで128種類

ASCII(アスキー)は7ビットで表せる0〜127の範囲を使います。組合せの数は2の7乗、つまり128種類です。この中には英大文字・英小文字・数字・記号のほか、改行などの制御文字も含まれます。128種類すべてが画面に描かれる文字という意味ではありません。

「A」のASCII値は10進数で65、16進数で41です。「B」は66、「a」は97なので、大文字と小文字は別の値です。また、文字の「0」は48です。数値のゼロと、画面に表示する数字の「0」は同一のデータではないことにも注意してください。

7ビットの規格なのに「英字は1バイト」と説明されるのは、通常の保存では8ビットの箱であるバイトへ格納するためです。「A」を8ビットで書くと01000001になります。ASCIIで定義された値の範囲と、保存する単位の大きさを混同しないようにしましょう。

ASCIIだけでは「あ」や「漢」を表せません。「文字に番号を付ける規格だから日本語にも使える」と考えず、どの文字を対象としているのか確認します。なお、8ビットへ拡張した各種の符号体系を、すべて同じASCIIとして扱うこともできません。

対象10進数の値16進数の値UTF-8のバイト列
A654141
a976161
0(文字)483030
半角スペース322020
LF(改行制御)100A0A

表の16進数と2進数の読み替えでつまずく場合は、基本情報のn進数と基数変換の解説で4ビットごとの対応を確認してください。この記事では変換手順そのものより、値が何を表すかに注目します。

Unicodeのコードポイントとは

Unicode(ユニコード)では文字にコードポイントという番号を割り当てます。「U+」に続く数字は16進数です。たとえばU+0041は「A」、U+3042は「あ」を指します。「U+」や先頭の0まで含めた文字列を、そのままファイルに保存するという意味ではありません。

U+0041の0041は16進数の41と同じ値です。U+3042は16進数の3042であり、10進数の3042ではありません。数値表現の違いを避けるため、コードポイントはU+付き、バイト列は2桁ずつ区切る、と表記を分けると見間違えにくくなります。

Unicodeのコードポイントの範囲はU+0000〜U+10FFFFです。ただし、範囲内のすべてに文字が割り当てられているわけではありません。また、U+D800〜U+DFFFはUTF-16のサロゲート用に予約されており、単独の文字としてUTF-8へ符号化する対象にはなりません。

初学者は、細かな範囲を全部暗記するより「番号の体系がUnicode、その番号をどう並べて保存するかがUTF-8など」と押さえるとよいですね。Unicodeという名前だけでは、ファイルがUTF-8なのかUTF-16なのか、また何バイトかは確定しません。

用語の区別と符号化形式の定義は、Unicode標準の第3章「Conformance」で確認できます。

UTF-8の8は文字のビット数ではない

UTF-8(ユーティーエフエイト)の8は、符号化の単位が8ビットであることを示します。「すべての文字を8ビットで表す」という意味ではありません。1個のUnicodeスカラー値を表すために、1〜4個のバイトを使う可変長の方式です。

必要なバイト数は、そのコードポイントの値に応じて決まります。U+0000〜U+007Fは1バイトなので、ASCIIの範囲は同じバイト値で表せます。「ABC」をASCIIとして保存してもUTF-8として保存しても、文字本体のバイト列は41 42 43で一致します。

この互換性は「ASCIIを含む文章なら何でもASCIIで保存できる」という意味ではありません。「ABCあ」では英字部分は1バイトずつですが、「あ」には別の3バイトが必要です。文字列全体をASCIIとして符号化しようとすると、日本語のところで表現できません。

表では符号化できる値の範囲を整理しています。3バイトの欄だけは途中にサロゲート範囲の除外があります。バイト数を調べるときは、U+付きの値をどの範囲に当てはめるかを先に確認します。

青いガラスの立方体を1個・2個・3個・4個の四列に並べた様子
UTF-8の1〜4バイトという長さの違いを表すイメージ
コードポイントの範囲UTF-8のバイト数例
U+0000〜U+007F1A、0、半角スペース
U+0080〜U+07FF2é(U+00E9)
U+0800〜U+FFFFのうちU+D800〜U+DFFFを除く3あ(U+3042)、漢(U+6F22)
U+10000〜U+10FFFF4😀(U+1F600)

UTF-8の範囲とバイト列の規則は、IETFのRFC 3629を根拠にしています。古い説明にある5〜6バイトの方式を、現在のUTF-8の計算へ持ち込まないでください。

「あ」を実際のバイト列へ変換する

青い木製の円盤と、三つの区画にガラス玉を一つずつ入れた容器
一つの文字を複数のバイトで表すことを考えるイメージ

「あ」のコードポイントU+3042を例に、番号と符号化結果の違いをもう少し詳しく見ます。16進数3042を2進数で16桁にすると0011 0000 0100 0010です。この値は3バイトの範囲に入るため、UTF-8では三つのバイトへ分けて格納します。

3バイトの基本形は1110xxxx 10xxxxxx 10xxxxxxです。xの部分がコードポイントの値を入れる場所で、左から4桁・6桁・6桁、合計16桁あります。先頭の1110や10はバイトの役割を示す部分なので、元の値だけを8ビットずつ切ればよいわけではありません。

0011000001000010を4・6・6桁に区切ると、0011、000001、000010です。それぞれを型にはめると11100011 10000001 10000010になります。16進数へ直すとE3 81 82、これが「あ」のUTF-8バイト列です。

復号するときは逆に、符号化の目印を取り除いてxのビットをつなぎます。こうして元の3042に戻り、Unicodeの対応から「あ」と解釈します。試験で変換規則が与えられたら、目印のビットと値のビットを別々に扱うと作業が安定します。

段階表現
コードポイントU+3042
値を2進数にする0011 0000 0100 0010
4・6・6桁に分ける0011 / 000001 / 000010
3バイトの型へ入れる11100011 / 10000001 / 10000010
UTF-8のバイト列E3 81 82

この例の3042は16進数4桁だから2バイト、という結論にはなりません。コードポイントの数値を表記する桁数と、符号化後のバイト数は別です。同様にU+0041は4桁で書かれていますが、UTF-8では41の1バイトです。

バイト列は通常、1バイトを16進数2桁で書きます。E3 81 82は2桁の組が三つなので3バイトです。E38182という連続表記でも同じ値を表せますが、学習中は区切りを入れると、コードポイントとの違いが見やすくなります。

UTF-16やUTF-32とどう違う?

UTF-8、UTF-16、UTF-32はいずれもUnicodeを表す方式ですが、使う単位が異なります。UTF-16は16ビットのコード単位を使い、対象の値によって1単位または2単位です。つまり、1コードポイントに2バイトまたは4バイトが必要になります。

UTF-16で補助平面の文字を表すときは、二つのコード単位から成るサロゲートペアを使います。「😀」は1コードポイントですが、UTF-16では2単位です。「Unicodeは2バイト」と覚えると、このような文字を説明できなくなります。

UTF-32は1個のUnicodeスカラー値に32ビット、つまり4バイトを使います。ただし、後半で説明するように、見た目の一文字が複数のコードポイントで構成されていれば、その全体が必ず4バイトになるわけではありません。固定長という説明には、何に対して固定長かという条件が付いています。

方式コード単位Aの本体あの本体😀の本体
UTF-88ビット1バイト3バイト4バイト
UTF-1616ビット2バイト2バイト4バイト
UTF-3232ビット4バイト4バイト4バイト

この表はBOMなどを除く文字本体だけの比較です。方式とコード単位の詳しい関係は、Unicode公式のUTF・BOM FAQで確認できます。問題文が「1文字を16ビットで表す」と仮定している場合は、その問題の条件に従い、現実の方式全体の性質とは区別してください。

基本情報の文字コードとバイト数の計算

ノートと鉛筆、そろばん、色分けした木の玉を置いた机
文字ごとの長さを分けて合計する計算のイメージ

計算前に確認する三つの条件

データ量を計算するときは、最初に「符号化方式」「数える文字の内容」「何をサイズに含めるか」を確認します。UTF-8かUTF-16かで答えが変わるため、文字数だけを見て式を作らないのがコツです。

次に、文字列を構成する値を確認します。UTF-8ならASCII文字、2バイトの文字、3バイトの文字、4バイトの文字を分けて数えます。「日本語だから全部同じ」とまとめず、与えられたコードポイントやバイト数の表があれば、それを基準にしてください。

最後に、文字列本体だけを求めるのか、改行・BOM・終端記号を含むのかを読み取ります。問題に含めると書かれていなければ、勝手に制御情報やファイルシステムの管理領域を追加しません。逆に、条件が書かれていれば計算から落とさないようにします。

実務のファイルサイズと、紙の上で文字本体だけを計算する問題は対象が違うことがあります。条件が足りない問題では、数字を一つに決めつけず「UTF-8でBOM・改行なしなら」という前提を付けると、何を計算したのか明確になります。

「Aあ😀」は3文字でも8バイト

UTF-8で「Aあ😀」を保存し、BOM・改行・終端記号を含めないとします。三つのコードポイントが並んでいますが、それぞれの長さは1、3、4バイトです。合計は1+3+4=8バイトになります。

実際のバイト列は41 E3 81 82 F0 9F 98 80です。16進数2桁の組を数えると八つになり、計算結果と一致します。文字ごとの内訳を表に書けば、すべて3倍する誤りや、絵文字を数え忘れる誤りを防ぎやすいですね。

文字コードポイントUTF-8バイト列長さ
AU+0041411バイト
あU+3042E3 81 823バイト
😀U+1F600F0 9F 98 804バイト
合計3コードポイント上から順に連結8バイト

同じ文字列をUTF-16で表すなら2+2+4=8バイト、UTF-32なら4+4+4=12バイトです。この例ではUTF-8とUTF-16の合計が偶然同じですが、方式が同じ意味だからではありません。「AAA」ならUTF-8は3バイト、UTF-16は6バイトで差が出ます。

文字の構成比でもサイズは変わります。UTF-8でASCII文字が20個、「あ」が10個、「😀」が2個なら、20×1+10×3+2×4=58バイトです。三つのグループへ分けて計算し、最後に足す方法を使えば、長い文字列でも全体を見失いにくくなります。

ビット数を聞かれたら、求めたバイト数に8を掛けます。上の58バイトは464ビットです。7ビットのASCIIという知識から、UTF-8で保存した英字部分だけ7倍することはありません。ここでは保存されたバイト列の大きさを求めています。

半角・全角だけで判断しない

半角・全角は表示や文字の種類を説明するときに使う言葉ですが、UTF-8のバイト数を一意に決める基準にはなりません。半角英字のAは1バイト、全角英字のA(U+FF21)は3バイトですが、半角カタカナのア(U+FF71)も3バイトです。

「半角だから1バイト」という覚え方をすると、アの計算を間違えます。画面の幅で判断するより、コードポイントがUTF-8のどの範囲に入るかを確認してください。また、同じ見た目の幅で表示されていても、文字そのものが同じとは限りません。

日本語の文字でも、たとえば「𠮷」はU+20BB7なのでUTF-8では4バイトです。「日本語は3バイト」は、よく使うひらがなや多くの漢字を扱うときの目安にはなりますが、例外のない定義として覚えると危険です。

Shift_JISなど別の方式では長さや表せる文字の範囲も異なります。ここで示したUTF-8の値を、別方式の問題へそのまま使わないでください。単語の暗記より「方式が変わればバイト列も変わる」という読み方を身に付けることが大切です。

文字表示上の呼び方の例コードポイントUTF-8
A半角英字U+00411バイト
A全角英字U+FF213バイト
ア半角カタカナU+FF713バイト
𠮷漢字U+20BB74バイト

見た目の1文字と番号の数が違う例

二つの部品をつなげた木製パズルと、分離した二つの部品
一つのまとまりが複数の要素で構成されるイメージ

「が」は、一つのコードポイントU+304Cで表せます。一方、「か」のU+304Bに結合濁点U+3099を続けた「が」という表し方もあります。適切な表示環境ではどちらも一つの「が」のように見えますが、コードポイントの数とUTF-8の長さは異なります。

前者は1コードポイントで3バイト、後者は2コードポイントで3+3=6バイトです。ここでは、見た目の文字数、コードポイント数、符号化後のバイト数という三つの数を分けて扱います。画面で一つに見えたことだけから、バイト数を決めることはできません。

利用者が一文字として受け取るまとまりを扱うときには、書記素クラスタという考え方があります。詳しい境界規則はUnicodeの仕様で定められています。最初から規則を暗記する必要はありませんが、「1文字」という言葉には数える単位の確認が必要だと知っておくとよいですね。

絵文字にも、複数のコードポイントを組み合わせるものがあります。ここで使った😀は一つのコードポイントなので4バイトですが、見た目が一つの絵文字なら何でも4バイトとは限りません。肌の色などの修飾や、結合した並びを含む場合は、その構成要素を合わせて数えます。

表現コードポイント数UTF-8の本体
が(U+304C)13バイト
か+結合濁点(U+304B U+3099)26バイト

この違いの根拠は、Unicode公式の文字・結合文字FAQとUnicodeの書記素クラスタ仕様(UAX #29)です。文字数制限のあるシステムでも、何を1文字として数えるかは確認が必要です。

改行とBOMはどこに加える?

UTF-8の文字列に改行を加える場合、LFなら0Aの1バイト、CRLFなら0D 0Aの2バイトです。「A」のあとに改行が一つあるファイルは、LFなら文字本体1+改行1=2バイト、CRLFなら1+2=3バイトになります。

改行は画面上で線や文字として見えなくても、データ量には入ります。複数行の問題では行と行の間だけにあるのか、最終行の末尾にもあるのかを確認してください。三行だから必ず改行を三つ加える、と決めるのではなく、保存される並びから数えます。

BOM(バイト順マーク)はデータの先頭に付くことがある印です。UTF-8ではEF BB BFの3バイトです。UTF-8自体にバイト順の区別はなく、BOMは符号化方式を示す署名として使われます。UTF-8ファイルのすべてに必須ではありません。

たとえば「ABC」をBOMなし・改行なしで保存すると3バイト、BOM付きなら6バイトです。BOMは各文字に3バイトずつ付けるのではなく、ファイル先頭の一回分として扱います。計算問題でも、BOMありという条件がある場合にだけ加算してください。

終端記号も自動的に加えるものではありません。プログラムの文字列用バッファで末尾にNULを置くという条件なら必要な分を足しますが、一般のテキストファイルのサイズへ何の指定もなく1バイトを追加するのは誤りです。

文字化けと変換を区別する

木製の立体を青と黄色の透明フィルター越しに見た様子
同じ情報でも解釈の方法で結果が変わることを考えるイメージ

文字化けの典型的な原因は、書き込み時と読み込み時で符号化方式が一致していないことです。UTF-8で保存されたバイト列を別の方式で解釈すると、違う文字に見えたり、無効な並びとして置換文字が表示されたりします。

ここで「読み方を指定すること」と「ファイルを別の方式へ変換すること」を分けてください。前者は今あるバイト列をどう解釈するか、後者は正しく読んだ文字を別のバイト列へ符号化し直すことです。拡張子を変えるだけでは、内部のバイト列は変換されません。

対応するときは、元のファイルを保持したまま、作成元が指定した符号化方式で開けるかを確認します。正しく読めることを確認してから、渡す先が求める方式を指定して保存します。文字化けした表示をそのまま上書き保存すると、元の文字へ戻せる情報を失う場合があります。

ただし、文字が表示されない原因は文字化けだけではありません。対応する字形がフォントにない場合や、元のデータが欠落している場合もあります。「四角が出たからUTF-8にすれば必ず直る」と考えず、保存方式と表示環境を順に確認すると切り分けやすくなります。

例題で単位と条件を確認する

以下は理解を確かめるためのオリジナル例題です。公式の過去問ではありません。先に自分で計算し、答えだけでなく「何を数えたか」を説明できるか確認してください。

問題条件答え
ASCIIの7ビットで表せる種類数は?7ビットの組合せを数える2⁷=128種類
「FEあ」をUTF-8で保存した長さは?BOM・改行・終端記号なし1+1+3=5バイト
「Aあ😀」をUTF-32で保存した長さは?文字本体のみ4+4+4=12バイト
「ABC」にLFとUTF-8のBOMを付けた長さは?末尾にLFが一つ、先頭にBOMが一つ3+1+3=7バイト
U+304BとU+3099のUTF-8合計は?二つのコードポイントを連結3+3=6バイト

最初の問題はビットの組合せを求める問題です。ASCII文字を何バイトに保存するかとは別なので、128という値に8を掛ける必要はありません。二つ目は英字部分と日本語部分を分ければ、全体を一律3倍する誤りを避けられます。

三つ目ではUTF-8の長さを使わず、指定されたUTF-32の条件を使います。四つ目は文字・改行・BOMを別々に求めてから足します。五つ目は画面の見た目ではなく、与えられた二つのコードポイントを対象にします。どの問題も、式より前に単位を確定するのがポイントです。

選択肢を読むときも、「ASCIIは8ビットで256種類」「UTF-8は常に1バイト」「Unicodeは必ず2バイト」「半角文字はすべて1バイト」という言い切りをそのまま信じないでください。規格の範囲、符号化の単位、文字本体の長さを混ぜていないかを確認します。

逆に、問題文が「1文字は2バイトとして計算する」と明示したモデル問題なら、その条件を使います。現実のUTF-8の説明を知っていても、与えられた仮定を無視して解かないことが大切です。一般の性質を聞いているのか、指定条件の計算なのかを見分けましょう。

Pythonで文字数とバイト数を実測

手元で確認できる環境があれば、Pythonで同じ文字列を数えると違いが見えます。Pythonのstrをlenで数える場合はコードポイント数、UTF-8へencodeしたbytesをlenで数える場合はバイト数になります。この二つの結果を並べて確認します。

text = "Aあ😀"
print(len(text))                 # 3
print(len(text.encode("utf-8"))) # 8
print(text.encode("utf-8").hex(" "))
# 41 e3 81 82 f0 9f 98 80

この例のencode(“utf-8”)はBOMや改行を自動追加していません。したがって、計算した8バイトと一致します。ファイルを書き出す処理で別途改行やBOMを付ければ、そのファイルサイズは変わります。

結合文字の例でも、len(“が”)は1、len(“が”)は2になります。どちらも見た目では一文字に見えることがありますが、lenは書記素クラスタを数える関数ではありません。別の言語やAPIでは数える単位が違うこともあるため、関数名だけで同じ挙動だと判断しないでください。

str.encodeの仕様はPython公式ドキュメントに掲載されています。コードポイント数と符号化後のサイズを分けて実測すれば、手計算の前提も確かめられます。

まとめ:基本情報の文字コードの覚え方

基本情報の文字コードは、ASCIIで文字と値の対応を学び、Unicodeでコードポイントを理解し、UTF-8でバイト列へ変換する、という順序で整理しましょう。番号の桁数、画面の文字幅、保存したバイト数は別の指標です。

計算では、符号化方式を確認し、文字ごとのバイト数を合計し、指定された改行やBOMだけを加えます。見た目の一文字が複数のコードポイントで成り立つ場合もあるため、「1文字は必ず同じバイト数」と覚えないことが大切です。

理解を問題で確かめたい方は、基本情報の過去問アプリで無料演習を進め、間違えた問題の符号化方式・単位・追加条件を確認してみてください。用語を学び直したい方は、基礎理論全体をつなげて学ぶと整理しやすくなります。

参考書をまだ持っていない初心者なら、いちばんやさしい基本情報技術者の教科書・問題集も選択肢です。すでに使いやすい参考書がある方は、まずその情報表現の章と演習を活用すれば十分です。購入前には対応年度・目次・試し読みを確認してください。この記事には広告リンクが含まれます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次