
入力フィールドに「30文字以内」と書いてあるのに弾かれたり、データベースに入れた文章が途中で切れたりするときは、文字数ではなくバイト数で上限を判定しています。バイト数は文字コードによって変わり、同じ文章でも文字数と一致するとは限りません。
文字数とバイト数の違いは日本語が何バイトになるかで表に出る
文字数は人が目で見て分かる文字の個数で、「あ」も「A」も「1」も1文字としてカウントします。画面に表示されているものがそのまま値になるので、環境が変わっても揺れません。
バイト数はその文章をコンピューターに保存するときに必要な大きさで、1バイトは8ビットです。どの文字に何バイトを使うかは文字コードで定まり、同じ「あ」でも文字コードが異なれば必要なバイト数が変わります。
文字の個数と保存に必要な大きさは別のものなので、文字数とバイト数は一致しません。英数字だけの文章ならたまたま一致することもありますが、日本語が混ざった時点でずれます。
"that subset only requires a single byte for processing and storage in UTF-8" — Unicode を策定している Unicode Consortium の FAQ より(英語のみのページ。ASCII の範囲は UTF-8 で1バイトで済む、という記述)公式情報を見る →
UTF-8では日本語の多くが3バイト、Shift_JISでは2バイト
UTF-8は文字によって使うバイト数が変わる文字コードで、英数字は1バイトです。日常的に使う日本語の多くは3バイトになり、ひらがなも漢字もこの3バイトの範囲に含まれます。
Shift_JISでは日本語が2バイトで、英数字はUTF-8と同じ1バイトなので、差が出るのは日本語の部分だけです。同じ100文字の日本語ならUTF-8で300バイト、Shift_JISで200バイトになります。
バイト数を書くときは、どの文字コードでカウントした値かを必ず添えてください。「日本語は3バイト」とだけ書くとShift_JISの環境では数が合いません。
半角カナもUTF-8では3バイト
半角カナはShift_JISでは1バイトなので、UTF-8でも少ないと思いがちです。しかしUTF-8では半角カナも3バイトを使います。
入力フィールドの上限に引っかかって全角カナを半角へ変換しても、UTF-8で処理するシステムでは保存に必要な大きさは小さくなりません。むしろ読みにくくなるだけです。
絵文字はUTF-8で4バイト
UTF-8は、日常的に使う範囲を超える文字を4バイトで表します。絵文字の多くも、この4バイトで表す文字です。
UTF-8での絵文字は、多くの日本語文字より1バイト大きくなります。バイト単位で上限が定められている入力フィールドに絵文字を入れると、見た目の文字数より早く上限に達します。
「半角1バイト・全角2バイト」が通じるのはShift_JISまで
「半角は1バイト、全角は2バイト」という覚え方はShift_JISを前提にしたものです。当時の環境ではこの覚え方で十分でしたし、いまもShift_JISのシステムでは成り立ちます。
UTF-8ではこの対応が崩れ、英数字は1バイトのままなのに日本語の多くは3バイト、絵文字は4バイトになります。半角と全角はもともと等幅フォントで表示したときの文字幅に関する区別で、バイト数を表すものではありません。
古い銀行や行政のシステムでは、Shift_JISを前提にしたバイト数の上限がいまも使われています。同じ「50バイトまで」でも、UTF-8とShift_JISのどちらで計算するかで収まる文字数が変わります。
改行コードもCRLFなら2バイト、LFなら1バイト
バイト数で見落としやすいのは改行です。この改行は画面に表示されませんが、文字と同じようにバイトを使います。
Windowsで作ったテキストはCRLFという2バイトの改行を、macOSとLinuxで作ったテキストはLFという1バイトの改行を使うのが一般的です。100行あればこの違いだけで100バイト変わります。
行数の多いCSVを作るときやバイト単位で上限が定められているファイルを処理するときは、改行の分も数に入れてください。1行あたり1バイトの差でも行数が増えれば無視できない量になります。
桁あふれと文字化けの原因はバイト数で見分けられる
現場で発生する困りごとはたいてい2種類あります。入れたはずのデータが途中で切れる桁あふれと、日本語が記号の羅列になる文字化けです。
桁あふれは保存先がバイト単位で上限があるときに発生します。データベースの列を255バイトで作ってあると、UTF-8の日本語なら85文字で埋まるので、文字数のつもりで設計しているとこの差に気づきません。
文字化けは、書いたときの文字コードと読んだときの文字コードが異なるときに発生します。文字化けしていると、バイト数が上限以内でも文字を読むことができません。末尾が欠けているのか文字が化けているのかを見れば、どちらが原因かを判断できます。
プログラムで取得した文字数は目で見た個数とずれることがある
プログラムで文字数を取ると、見た目の文字数と合わないことがあります。この差はJavaやC#の文字列が内部でUTF-16を使っていて、長さを取る関数が文字の個数ではなくコードユニットの数を出力するためです。
UTF-16では日常的に使う文字を1つのコードユニットで表せますが、その範囲を超える文字は2つ必要になります。絵文字の多くは後者なので、絵文字1つだけの文字列でも長さは2です。
またExcelでは文字数とバイト数を別の関数で計算します。LEN関数は文字数を、LENB関数はバイト数を出力するので、同じセルでも使う関数によって結果が変わります。
"BMP characters require one 16-bit code unit to process or store, whereas supplementary characters require two" — Unicode Consortium の FAQ より(英語のみのページ)公式情報を見る →
"文字数またはバイト数を調べる文字列を指定します。 スペースは文字として数えられます。" — Microsoft 公式サポートページより公式情報を見る →
バイト数は文字コードと切り離せない量
バイト数は文字コードによって変わります。つまり、日本語の多くはUTF-8では1文字3バイト、Shift_JISでは2バイトになり、同じ文章でもバイト数が変わります。
とくに半角とバイト数の関係は覚え直しておいてください。「半角だから1バイト」というのはShift_JISの話で、UTF-8では半角カナも3バイトを使うので、入力フィールドで弾かれたときに全角カナを半角カナへ変換してもUTF-8のシステムではバイト数は変わりません。
FAQ
- 日本語1文字は何バイトですか?
- 文字コードによります。UTF-8では日常的に使う日本語の多くが3バイト、Shift_JISでは2バイトです。どちらで保存されているかを決めないと、バイト数は出せません。
- 半角に修正すればバイト数は少なくなりますか?
- カナならShift_JISでは少なくなりますが、UTF-8では少なくなりません。UTF-8では半角カナも3バイトを使うため、全角カナを半角カナに変換しても保存に必要な大きさは変わりません。
- 絵文字のバイト数はいくつですか?
- UTF-8では4バイトを使う絵文字が多くあります。日本語の文字よりバイト数が多いので、バイト単位で上限のある入力フィールドでは見た目の文字数より早く上限に達します。
- 文字数とバイト数はどうやって調べますか?
- ExcelならLEN関数とLENB関数で両方を出せます。ソフトを入れずにブラウザで調べたいときは、文字数カウントツールを使ってください。



