文字列のバイト数カウント(エンコーディング別)

入力した文字列がUTF-8・Shift_JIS・EUC-JP・UTF-16・JIS(ISO-2022-JP)でそれぞれ何バイトになるかを計測します。データベースの文字数制限やフォームの入力上限を確認する際に便利です。

文字数とバイト数は別物です

「10文字なのに30バイト」という事態は、日本語を扱っていれば日常的に起こります。**同じ文字列でもエンコーディングによってバイト数が変わる**からで、UTF-8 では日本語1文字が3バイト、絵文字なら4バイトを占めるのに対し、Shift_JIS では日本語1文字が2バイトです。このツールは入力した文字列が UTF-8・Shift_JIS・EUC-JP・UTF-16・JIS の5方式でそれぞれ何バイトになるかを同時に表示します。

**あわせて表示している「UTF-16コード単位数」は、JavaScript の `.length` が返す値そのものです。** ここが見落とされやすい落とし穴で、絵文字や一部の漢字はサロゲートペアという2つの単位で表されるため、**人が1文字と数えるものを `.length` は2と数えます。** 入力欄の文字数制限を `.length` で実装すると、絵文字を含む入力が想定より早く弾かれるのはこのためです。データベース側の制限も、`VARCHAR(255)` がバイト数を指すのか文字数を指すのかは製品と設定によって違うため、両方の数字を見ておくと判断を誤りません。

使い方

  1. 文字列を入力する 貼り付けた瞬間に集計されます。改行を含めてもかまいません。
  2. 文字数とバイト数を見比べる **文字数は1つでも、UTF-8では3バイトということが起こります。**
  3. 対象のエンコーディングを選んで読む 保存先や送信先が使っている方式の行を見てください。
  4. UTF-16コード単位数を確認する **JavaScript の `.length` で制限をかけている場合は、この数字が実際の判定値です。**

使いこなすためのヒント

  • UTF-8では半角英数字は1バイト、ひらがな・カタカナ・漢字などの日本語は多くの場合3バイトになるため、同じ文字数でも英語と日本語ではバイト数が大きく異なります。
  • データベースの列がVARCHAR(255)のようにバイト数ベースで文字数制限を設けている古いシステムの場合、日本語を含む文章は英語の文章よりずっと早く上限に達してしまいます。
  • 絵文字の多くはサロゲートペアという2つのコード単位で表現され、UTF-8で4バイト・UTF-16でも4バイトになるため、SNSの文字数カウントで思ったより早く上限に達する原因になります。
  • すでにバイト数の数値が分かっていて、それをKB・MBなど他の単位に変換したい場合は、姉妹ツールの「バイト単位変換」をご利用ください。このツールは文字列からバイト数を求める逆方向の計算を担当します。

活用シーン

データベースの桁あふれを防ぐ

**格納先がバイト数で制限している場合、日本語は想定の3分の1しか入りません。** 登録前に確かめられます。

フォームの入力上限を設計する

文字数で制限するのか、バイト数で制限するのかを決める材料になります。

レガシーシステムへ連携する

固定長のファイルや Shift_JIS 前提の連携では、バイト数がそのまま桁位置になります。

絵文字の扱いを検証する

**サロゲートペアを含む文字列が、想定どおりの長さとして扱われるかを確かめられます。**

文字コードの用語

UTF-8
世界中の文字を1〜4バイトの可変長で表す方式です。**ASCII は1バイト、日本語は3バイト、絵文字は4バイト**が目安になります。
Shift_JIS
日本語向けの方式で、**日本語1文字が2バイト**に収まります。古いシステムや固定長ファイルで今も使われています。
EUC-JP
UNIX 系で使われてきた日本語の方式です。日本語1文字は通常2バイトです。
UTF-16
16ビットを単位として文字を表す方式です。**JavaScript の文字列はこの単位で数えられます。**
サロゲートペア
UTF-16 で1つの単位に収まらない文字を、**2つの単位の組で表す仕組み**です。絵文字や一部の漢字が該当します。
ISO-2022-JP
エスケープシーケンスで文字集合を切り替える方式で、日本語メールで使われてきました。JIS コードとも呼ばれます。

よくある質問

文字数は「見た目の文字がいくつあるか」を数えるのに対し、バイト数は「その文字列をコンピューター上のデータとして保存・送信する際に何バイト(何オクテット)必要か」を表します。ASCII文字は1文字1バイトで一致しますが、日本語などの多バイト文字を含む文章では文字数とバイト数が大きくずれます。

UTF-8は文字ごとに1〜4バイトの可変長で符号化する仕組みで、日本語の大半(ひらがな・カタカナ・常用漢字)は3バイトになります。一方Shift_JISは日本語の大半を2バイトで符号化するため、同じ日本語の文章でもUTF-8のほうがバイト数が大きくなるのが一般的です。

データベースの種類・列の文字コード設定によって異なります。MySQLのVARCHAR(n)は基本的に「n文字」で制限されますが、内部的にはバイト数の上限(インデックスに使えるキー長など)も別途存在するため、絵文字を含む文章でエラーになるケースがあります。実際の挙動は使用しているDBMSのドキュメントで確認してください。

半角英数字・記号はUTF-8・Shift_JIS・EUC-JPのいずれでも1バイトで表現されますが、全角文字(ひらがな・カタカナ・漢字・全角記号)はエンコーディングに応じて2〜3バイトになります。同じ「10文字」の文章でも、半角のみなら10バイト、全角のみなら20〜30バイトと大きな差が生まれます。

このツールは文字列を入力すると、その文字列のバイト数をエンコーディングごとに計算します。一方「バイト単位変換」ツールは、すでに分かっているバイト数(例: 1,500,000バイト)をKB・MB・GBなどの単位に変換するツールです。「文字列→バイト数」を求めたいときは本ツール、「バイト数→他の単位」を求めたいときはバイト単位変換ツールをお使いください。
ツールくん

余談ですが ― SNSの文字数制限とバイト数の知られざる関係

古いバージョンのMySQLで使われていた「utf8」文字セットは、実はUnicodeの絵文字(U+10000以降の補助文字面)を保存できない仕様でした。UTF-8は本来4バイトまでの可変長エンコーディングですが、MySQLの「utf8」は歴史的経緯から最大3バイトまでしか扱えず、絵文字を含む文章をINSERTしようとするとエラーになる不具合が長年報告されていました。現在は4バイトまで正しく扱える「utf8mb4」への移行が推奨されており、文字コードとバイト数の仕様を正確に理解しておくことの重要性を示す代表例になっています。

かつてTwitter(現X)が140文字制限を採用していた時代、日本語ユーザーは140文字でも十分に長い文章を書けるのに対し、英語ユーザーは140文字では単語数にして20〜30語程度しか書けず不公平だという議論がありました。これは英語がアルファベット1文字=1文字なのに対し、日本語は漢字1文字に多くの情報量が詰まっているためです。後にTwitterは日本語などの言語を「1文字=1カウント」、英語などを一部「2バイト=1カウント」で計算する独自の重み付け方式を導入し、言語間の公平性を調整しました。

携帯電話のSMSにも同様の事情があります。GSM方式のSMSは1通あたり通常160文字までですが、絵文字や日本語など7ビットGSM文字セットに含まれない文字を1つでも含むと、エンコード方式がUCS-2(UTF-16相当)に切り替わり上限が70文字まで一気に減少します。「日本語を1文字使っただけで送信可能な文字数が半分以下になる」という現象は、まさにこの記事のテーマである文字コードとバイト数の関係が引き起こす典型例です。