テキストから2進数へ:文字列をバイトの並びとして見る
この変換でわかること
テキストをUTF-8でバイト列に符号化し、各バイトを8桁の2進数として書き出します。ここに計算はなく、文字を対応表で引いて書き出すだけですが、得られるのはその文字列が実際に保存・送信されるときの0と1の並びそのものです。
ASCIIではなくUTF-8を使う理由
ASCIIが定義するのは128文字だけで、英語は快適に収まりますが、それ以外はほとんど表現できません。UTF-8は最初の128文字をASCIIと同一に保ち、残りを2、3、4バイトに振り分けます。だから英文はASCIIと同じバイト列になり、日本語の文字や絵文字も扱えます。Aが1バイト、漢字の中が3バイトになるのはこのためです。
テキストと2進数の変換表
短い文字列とそのバイト列です。見どころは複数バイトの行で、1文字がどのように複数のバイトに分かれ、それぞれがどんな先頭ビットを持つかが分かります。
| テキスト | 2進数 |
|---|---|
| A | 01000001 |
| Hi | 01001000 01101001 |
| OK | 01001111 01001011 |
| 123 | 00110001 00110010 00110011 |
| ! | 00100001 |
| Go | 01000111 01101111 |
想定外のバイト数に驚くとき
テキストを扱っていて最も戸惑うのは、見た目より長い文字列です。5文字が5バイトのこともあれば15バイトのこともあり、文字数で表した上限はバイト数の上限に必ず破られます。バイト列を見れば、複数バイトの文字の先頭ビットが総バイト数を教えてくれるので、感覚ではなく事実として把握できます。
文字数とバイト数は別物
データベースのカラム、APIの制限、ヘッダのフィールドがバイト単位で決まっているなら、文字数ではなくバイト数を数えてください。変換結果のまとまりの個数がそのままバイト数なので、制限が実際に見ている値と一致します。
よくある質問
テキストはどうやって2進数になるのですか?
各文字をUTF-8の符号化表で引いて1つ以上のバイト値に置き換え、それぞれのバイトを8桁の2進数として書きます。英字のAは65、つまり01000001で、最初のASCIIの範囲に入るためちょうど1バイトです。
日本語の1文字が複数バイトになるのはなぜですか?
UTF-8は256文字よりはるかに多くの文字を扱う必要があるため、最初の128文字の外側は2、3、4バイトに分けて表します。漢字の中は3バイトなので、この変換では8桁の組が3つ並びます。
ASCIIでの変換と同じですか?
英数字だけのテキストなら同じです。UTF-8は最初の128文字をASCIIとバイト単位で同一になるよう設計されているので、Helloはどちらでも同じ結果になります。アクセント記号付きの文字や通貨記号、日本語が入った瞬間に両者は分かれます。
バイトを空白で区切るのはなぜですか?
連続した0と1は読みにくく数え間違いも起きやすいからです。8桁ずつ空白で区切るとバイトの境界がそのまま見えます。この区切りの空白は逆方向の変換では無視されるので、ここで出力した文字列をそのまま貼り戻せます。
絵文字も変換できますか?
変換できます。絵文字は3バイトで届く範囲より上にあるため、UTF-8では多くが4バイトで表され、ここでは8桁の組が4つ並びます。短い英単語より1文字のほうが長くなることも珍しくありません。