文字列のバイト数カウント(エンコーディング別)
入力した文字列が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つでも、UTF-8では3バイトということが起こります。**
- 対象のエンコーディングを選んで読む 保存先や送信先が使っている方式の行を見てください。
- 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 コードとも呼ばれます。
よくある質問
余談ですが ― 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文字使っただけで送信可能な文字数が半分以下になる」という現象は、まさにこの記事のテーマである文字コードとバイト数の関係が引き起こす典型例です。