UTF-8バイトビューア

文字ごとのUTF-8バイトとUnicodeコードポイントを分析

0 0

UTF-8バイトビューアについて

このツールは入力をコードポイント単位に分け、1文字ずつブラウザ内蔵のTextEncoderでUTF-8に変換してバイト列を表示します。「文字数」という言葉は、コードポイント数、UTF-16のコードユニット数、人が見て1文字と感じる単位(書記素クラスタ)の少なくとも3通りの意味を持ちますが、このツールが数えるのはコードポイントで、バイト数はUTF-8基準です。

データベースの列長、APIのバイト制限、ファイル名の長さ制限などで、見た目は短いのに「長すぎる」と言われたときに原因を確かめるのに向いています。

同じ1文字の3つの長さ

Unicodeは文字ごとに番号(コードポイント)を割り当て、その番号をどうバイトで書くかは符号化方式が決めます。UTF-8は1〜4バイト、UTF-16は2バイトのコードユニットを1〜2個使います。JavaScriptのstr.lengthやJavaのString.length()はUTF-16のコードユニット数を返すので、絵文字を含むとこのツールの文字数と一致しません。

  • A(U+0041):UTF-8 41、1バイト/UTF-16 1ユニット
  • é(U+00E9):UTF-8 C3 A9、2バイト/UTF-16 1ユニット
  • あ(U+3042):UTF-8 E3 81 82、3バイト/UTF-16 1ユニット
  • 😀(U+1F600):UTF-8 F0 9F 98 80、4バイト/UTF-16 2ユニット(D83D DE00)

バイト列を手で読み解く

RFC 3629はコードポイントの範囲ごとにビットの型を決めています。U+0000〜007Fは0xxxxxxx、U+0080〜07FFは110xxxxx 10xxxxxx、U+0800〜FFFFは1110xxxx 10xxxxxx 10xxxxxx、U+10000〜10FFFFは11110xxxに続く3バイトです。

「あ」はU+3042、2進数で0011 0000 0100 0010。16ビットを4・6・6に分けると0011/000001/000010で、型に入れると11100011 10000001 10000010、つまりE3 81 82です。先頭バイトの上位の1の数がそのシーケンスの長さを表し、続くバイトはすべて10で始まります。そのため途中から読み始めても次の文字の境界が分かり、0x80未満のバイトは必ずASCIIそのものです。Shift_JISの2バイト目に0x5C(\)が現れて「表」「ソ」などが文字化けやエスケープ事故を起こした、いわゆる5C問題がUTF-8では起こらないのはこのためです。

ひらがな・カタカナ・常用漢字はこの3バイト区間にあります。Shift_JISでは2バイトだったので、日本語中心の文章はUTF-8にすると約1.5倍になります。

見た目1文字が複数行に分かれるとき

ツールはコードポイントごとに1行を作ります。見た目は1文字なのに複数行が出る場合、それ自体が手がかりです。

  • 家族の絵文字👨‍👩‍👧:男性・ZWJ(U+200D)・女性・ZWJ・女の子で5コードポイント、18バイト。ZWJはE2 80 8Dです。
  • 肌の色付き👍🏽:U+1F44DとU+1F3FDの2つで8バイト。
  • macOSで作ったファイル名の「が」:か(U+304B)+結合用濁点(U+3099)の2行、6バイト。NFD(分解形)と呼ばれる形で、Windowsで入力した「が」(U+304C、E3 81 8C)とは文字列比較で一致しません。
  • 「𠮷」(つちよし、U+20BB7)は4バイトで、JavaScriptのlengthは2になります。人名で使われるため、住所録や予約システムでよく問題になります。

3バイトと4バイトの境目が問題になる場所

MySQLの旧来のutf8(正式名utf8mb3)は1文字最大3バイトしか保存できず、絵文字や𠮷のような4バイト文字でエラーになったり切り捨てられたりします。utf8mb4に変える必要があります。

バイト数で文字列を切る処理もよくある落とし穴です。日本語は3バイト単位なので、100バイトで切ると34文字目の先頭1バイトだけが残り、不正なバイトとしてU+FFFD(�)に置き換えられます。このツールで累積バイトを見て、切る位置を決められます。

見えない文字を探す

スペースは␣、タブと改行は\t・\n・\r、その他の制御文字は\x1Bのようなラベルで表示されます。空白に見えるUnicodeの空白文字にもラベルが付きます。U+00A0(ノーブレークスペース、C2 A0)は[NBSP]、U+200B(ゼロ幅スペース、E2 80 8B)は[ZWSP]、U+FEFF(BOM、EF BB BF)は[BOM]、U+3000(全角スペース、E3 80 80)は[IDSP]と表示され、ZWJ・ZWNJ・WJ・SHYも同様です。コピーした値が検索や照合で一致しないときは、これらのラベルがないか確認してください。

例

絵文字1つでDB保存が失敗する理由

入力
いいね😀
結果
4文字、13バイト — E3 81 84 / E3 81 84 / E3 81 AD / F0 9F 98 80

かな3文字で9バイト、絵文字が4バイト。utf8mb3の列はF0で始まる4バイト文字を受け付けません。JavaScriptのlengthは5です。

同じに見えるファイル名

入力
が(macOSのファイル名からコピー)
結果
2行:U+304B E3 81 8B / U+3099 E3 82 99 — 6バイト

キーボード入力の「が」は1行E3 81 8C。NFCに正規化するまで別の文字列です。

Webページからコピーした数値

入力
1 000円
結果
1と0の間の行がC2 A0 — U+00A0

通常のスペース(20)ではありません。split(" ")では分割されません。

使い方

  1. テキストを入力または貼り付けます。
  2. 各行で文字、コードポイント、UTF-8バイトを確認します。
  3. 上部で合計の文字数(コードポイント)とバイト数を見ます。
  4. 必要ならヘックスダンプをコピーして他のバイト列と照合します。

主な用語

コードポイント
Unicodeが文字に割り当てた番号。U+0000〜U+10FFFF。
コードユニット
符号化方式の最小単位。UTF-8は1バイト、UTF-16は2バイト。
サロゲートペア
UTF-16でU+10000以上を表す2つのコードユニット(D800〜DBFFとDC00〜DFFF)。
NFC/NFD
Unicode正規化形式。NFCは合成済みの形、NFDは基底文字と結合文字に分解した形。

よくある質問

日本語はUTF-8で何バイトですか?

かな・常用漢字は3バイトです。𠮷や𩸽のような第2面(U+20000以降)の漢字は4バイトです。

絵文字は必ず4バイトですか?

1コードポイントの絵文字は多くが4バイトですが、☺(U+263A)のような古い記号は3バイトです。肌の色や家族の組み合わせは複数のコードポイントなので8〜25バイト以上になります。

文字数カウントツールと結果が違います。

このツールはコードポイントを数えます。書記素クラスタで数えるツールなら家族絵文字は1、このツールでは5です。

Shift_JISのバイトも見られますか?

いいえ、UTF-8のみです。

関連ガイド

出典

基準日:

プライバシーとデータの扱い