テキスト / 16 進数変換

テキストを 16 進数へ、16 進数をテキストへ。UTF-8 か UTF-16 のバイトを、スペース区切り、配列、エスケープ、16 進ダンプで書き、どの形からもテキストに戻せます。

入力
出力
E3 81 93 E3 82 93 E3 81 AB E3 81 A1 E3 81 AF

文字列を、格納されているバイトのまま見る

プログラムが扱う文字列は、どれもその下ではバイトの並びで、このページはそれを 16 進数で、1 バイトにつき 2 桁で書き出します。Hello と入力すると 48 65 6C 6C 6F になり、1 文字に 1 バイト、最後のバイト以外はそれぞれの後ろにスペースが入ります。代わりに方向を「16 進数からテキスト」にして、ログやデータベース、デバッガーから取った 16 進数を貼り付ければ、そのバイトが保持しているテキストが戻ってきます。

同じテキストでも、エンコーディングが違えばバイトも違います。このページの数字が何であるかを決めるのは「単位」です。最初は UTF-8 で、ウェブのエンコーディングです。そこでは H は 48 というバイト、א は D7 90 というバイトです。UTF-16 LE と UTF-16 BE はどちらの文字にも 2 バイトを使い、並びは互いに逆です — H なら 48 00 か 00 48。一方「コードポイント」はバイトをまったく介さず、Unicode が割り当てる番号を書きます。א なら U+05D0 です。どの単位が設定されていても、書くテキストにも読む 16 進数にも同じように当てはまり、そのまま保たれます。貼り付けた 16 進数がほかの単位のものに似ていれば、ページはその単位を勧めることがありますが、単位を動かすのはあなたのクリックだけです。

1 バイトに 16 進数 2 桁

1 バイトが保持するのは 256 通りの値、0 から 255 のどれかです。16 進数は 16 ずつ数え、数字の 0 から 9 の後、10 から 15 には A から F を使います。16 の 16 倍は 256 なので、16 進数 2 桁でどのバイトも表せ、3 桁目が要ることはありません。00 は 0、7F は 127、FF は 255 です。H は 72、つまり 16 が 4 つと 8 なので、そのバイトは 48 です。

16 進数の 1 桁は、ちょうど 4 ビット、つまり半バイトを表します。48 の 4 は 0100、8 は 1000 で、並べると H の 8 ビット、01001000 になります。ページはどのバイトも 2 桁とも残すので、改行は 0A、スペースは 20 です。そしてどのバイトも同じ幅なので、16 進数はバイトのあいだに何もなくても読み戻せます。4869 は Hi です。

16 進数の英字は、大文字でも小文字でも意味は同じです。ページは「小文字」を選ばない限り大文字で書くので、é は C3 A9 か c3 a9 になります。読むときはどちらも受け付け、1 回の貼り付けに両方が混ざっていてもかまいません。

貼り付け先に合わせた 5 つのスタイル

16 進数では、「スタイル」が同じバイトを 5 通りに並べ、どれも 16 進数が次に向かう先に合わせてあります。Hi、つまり 48 と 69 の 2 バイトなら、次のとおりです。

  • 「スペース区切り」は 48 69 で、バイトのあいだにスペースが入ります。いちばん読みやすく数えやすく、ページが開いたときのスタイルです。
  • 「区切りなし」は 4869 で、数字が続けて並びます。値を 1 つの 16 進数の文字列として受け取る欄やパラメーター向けです。
  • 「配列」は 0x48, 0x69 で、どのバイトも前に 0x の付いた数になり、あいだにカンマが入ります。C、C#、JavaScript、Python、Go のバイト配列に、そのまま貼り付けられます。
  • 「エスケープ」は \x48\x69 で、どのバイトも \x とその 2 桁で書かれます。C の文字列や、b'\x48\x69' のような Python のバイト列リテラルの中で、バイトを書く書き方です。
  • 「16 進ダンプ」はバイトを行に並べ、各行がどこから始まるかと、同じバイトをテキストにしたものを横に添えます。次の節で 1 つ読んでみます。

読み取りは 5 つすべてを受け付け、バイトを変えないほかの書き方も受け付けます。48:69 のようなコロン、48-69 のように .NET の BitConverter.ToString が書くハイフン、各バイトの前の 0x や 0X、そして貼り付け全体を一度囲んだ丸括弧、角括弧、波括弧、引用符です。スタイルと大文字・小文字は書くときにしか関係しないので、方向が「16 進数からテキスト」のときは、どちらの設定も消えます。

「エスケープ」には落とし穴が 1 つあります。JavaScript の文字列や、バイト列リテラルではない普通の Python の文字列の中では、\x はバイトではなく文字を表すので、そこでの \xD7\x90 は 2 つの文字で、UTF-8 のバイトが D7 90 である א ではありません。ASCII を超えるなら、バイトはバイトを受け取るものに渡してください。

16 進ダンプを列ごとに読む

16 進ダンプはバイトを 1 行に 16 個ずつ並べ、両側に、それを探す助けになる列を置きます。「16 進ダンプ」で書くと、Hello, World! と改行は 1 行に収まります。最初が 00000000 で、これはオフセット、つまりその行の最初のバイトがゼロから数えてどこにあるかを 16 進数 8 桁で表したものです。次に 14 個のバイトが、8 個と 6 個に分かれて並び、前半と後半のあいだはほかより広く空きます。そして |Hello, World!.| が同じバイトを文字として示し、印字可能な ASCII でないバイトは、改行も含めて、どれも点で表されます。最後の行には 0000000E だけがあり、これは 14、つまり次のバイトが来るはずの位置で、したがって長さです。これが hexdump -C の出力する形です。

  • 「16 進数からテキスト」を選び、単位が「コードポイント」以外なら、貼り付けた 16 進ダンプはバイトだけが読まれます。テキストの列は読み取りから外され、どのオフセットもバイトとしては読まれず、結果の下の知らせが、入力を 16 進ダンプとして読んだことを伝え、その形を示します。
  • そのように読まれる形は 2 つです。hexdump -C の形と、xxd がオプションなしで出力する形で、後者では各オフセットの後にコロンが続き、バイトは 4 桁ずつのグループで並びます。xxd -p が出力する素の 16 進数は形を必要とせず、ほかの 16 進数と同じように読まれます。
  • hexdump -C は、上の行と同じ内容を繰り返す行の代わりに、* だけの行を出力します。ページはそうした行を下のオフセットから埋め戻すので、バイトは欠けずに戻ってきます。
  • 最初のもの以外のオフセットは、hexdump -C の最後の行にある長さも含めて、どれもその上のバイトから導かれなければならず、そうでない行は誤って読まれる代わりに、そこで拒否されます。抜け落ちた行、失われたバイト、打ち間違えたオフセットが見つかるのはそこです。後ろにオフセットが来ないものは確かめられないので、最初の何行かが欠けた 16 進ダンプや、後ろに長さの行がない末尾 — xxd はその行を書きません — は、残っているものとして読まれます。

UTF-16 LE と、1 バイトおきに 00 が来る理由

Windows はテキストを、下位バイトが先に来る UTF-16 で保持し、これが UTF-16 LE です。.NET ではこれが Encoding.Unicode で、SQL Server も NVARCHAR の値を同じ形で格納します。UTF-16 は U+FFFF までの各文字に 2 バイトを与え、U+00FF まで — 英語の文字、数字、é、その他の Latin-1 — では上位バイトが 00 です。下位バイトが先なので、そのゼロが各文字の後ろに来ます。Hi は 48 00 69 00 です。

SQL Server は VARBINARY の値を 0x とその 16 進数で表示するので、Hi を保持する NVARCHAR を VARBINARY にキャストすると 0x48006900 と表示されます。UTF-8 を選んだままそれをここに貼り付けると、テキストは H、NUL、i、NUL として出てきます。その下の知らせは、ラテン文字のテキストを UTF-8 ではなく UTF-16 で書いたときと同じように 1 バイトおきに 00 になっていると伝え、その横に「UTF-16 LE に切り替える」があります。それを押すと、同じバイトが Hi と読めます。

UTF-16 BE は逆に上位バイトを先に置くので、そこでは Hi は 00 48 00 69 になり、UTF-16 LE で D0 05 の א は 05 D0 になります。各ペアの先頭の位置にゼロがあると、知らせは UTF-16 BE を勧めます。U+00FF を超える文字がテキストに入ると、知らせは何も言いません。その文字の上位バイトは 00 ではないからです。知らせが出るのは、1 バイトおきに 00 であるところだけです。

先頭に置かれるバイト順マーク

テキストは U+FEFF で始まることがあります。何も表示しない文字で、バイト順マークとしてそこにあります。UTF-16 ではその 2 バイトが、後に続くすべてのペアの順序を示し、UTF-16 LE なら FF FE、UTF-16 BE なら FE FF です。UTF-8 では EF BB BF の 3 バイトで、テキストが UTF-8 であることを示す署名です。UTF-8 には順序が 1 つしかありません。

ページはマークを取り除かずに残します。選んだ単位そのもののマークで始まる 16 進数は、U+FEFF で始まるテキストとして読まれ、知らせがマークを残したことを伝えます。ですから、そのテキストをもう一度書けば、マークも含めて同じバイトになります。もう一方の UTF-16 の順序のマークで始まる 16 進数や、UTF-8 を選んでいるときに UTF-16 のマークで始まる 16 進数には、バイトが別の単位のマークで始まっているという知らせが出て、その横に、マークが示す順序へ切り替えるボタンが並びます。先頭以外の場所では、U+FEFF はふつうの文字で、知らせは出ません。

テキストにならないバイトは U+FFFD で表示

どのバイト列も、選んだ単位でテキストになるとは限りません。最後のバイトが欠けた文字、古いコードページが é に使う E9 のような迷い込んだバイト、UTF-16 の末尾に残った半端なバイトは、どれも何も綴りません。それでも、壊れたバイト列が 1 つあっても、貼り付けたもの全体が駄目になるわけではありません。それぞれが置換文字の U+FFFD に置き換えられ、ほかはすべてふつうに読まれます。

そのとき知らせがその数を伝え、最初のものを、バイトの中での位置、それに対してあなたが書いた数字、そしてその行と列で示します。西ヨーロッパのテキストのための Windows のコードページである Windows-1252 で保存した Café は 43 61 66 E9 で、そこでは é は E9 という 1 バイトです。UTF-8 として読むと Caf と U+FFFD になって戻り、知らせは、1 行目、10 列目に E9 と書かれた 4 バイト目を示します。UTF-8 では、この語は 43 61 66 C3 A9 です。

知らせが数えるのはバイトではなくバイト列です。😀 の 4 バイトのうち 3 バイトである F0 9F 98 は、1 つの U+FFFD になります。そして、テキストに本当に入っている U+FFFD、つまり EF BF BD というバイトは、テキストとして読まれ、まったく数えられません。ですから、知らせが扱うのはいつも、読めなかったバイトだけです。

16 進数をファイルに戻す

読み取りは、テキストと一緒にバイトも渡してくれます。方向が「16 進数からテキスト」で、UTF-8、UTF-16 LE、UTF-16 BE のどれかを選んでいれば、「ダウンロード」は bytes.bin という名前のファイルとして、読み取ったバイトをそのまま保存します。テキストにならなかったバイトも含め、何かが置き換えられる前のバイトです。xxd -r が 16 進ダンプに対して行う仕事です。バイトではないコードポイントには「ダウンロード」はなく、持ち帰るものが数字である、書く方向のときにもありません。

ですから、一度もテキストではなかったものの 16 進数も、欠けずに戻ってきます。PNG 画像はどれも 89 50 4E 47 0D 0A 1A 0A の 8 バイトで始まります。UTF-8 として読むと、U+FFFD、PNG の文字、4 つの制御文字として表示され、テキストでない 1 つのバイト列についての知らせが出ます。そして「ダウンロード」は 8 バイトすべてを正確に保存します。バイトには名前がないので、ファイルの名前はいつも bytes.bin です。保存したら、image.png のように、それ自身の名前を付けてください。

文字そのもの、そのビット、あるいは数を調べるなら

文字が何であるか — 名前、カテゴリ、目に見えない文字の一つかどうか — を知るには、「Unicode 文字インスペクター」がテキストをコードポイント 1 つずつに分解し、それぞれの UTF-8 のバイトもあわせて表示します。

「テキスト / 2 進数変換」は、このページそのものを 2 進数で開いたもので、そこでは UTF-8 が従うパターンを、どのバイトでも最初のビットに読み取れます。そして、数はテキストではありません。ここで入力した 255 は 2、5、5 という数字、したがって 32 35 35 というバイトですが、「基数変換ツール」は 255 を量として受け取り、16 進数で ff と書きます。

よくある質問

16 進数は、どうやってテキストに変えますか?
「16 進数からテキスト」を選んで 16 進数を貼り付け、単位を、それが書かれたエンコーディングに合わせてください。たいていのテキストなら UTF-8、Windows や .NET の文字列、あるいは NVARCHAR の列から取った 16 進数なら UTF-16 LE です。バイトのあいだのスペース、カンマ、コロン、ハイフン、バイトの前の 0x や \x、全体を一度囲むものは読み飛ばされ、大文字も小文字も読めます。
テキストの文字と文字のあいだに NUL が入るのはなぜですか?
その 16 進数は、おそらく UTF-8 として読まれた UTF-16 LE です。UTF-16 LE は英語の各文字を、ASCII の値とその後の 00 という 2 バイトで書き、UTF-8 はそのゼロの一つひとつを、独立した文字 NUL として読みます。UTF-16 LE を選ぶか、ページが知らせの横に切り替えボタンを出していればそれを押すと、文字の間が詰まります。
16 進数の中のアクセント付きの文字が、なぜ U+FFFD になるのですか?
おそらく、その 16 進数は Windows-1252 のような古いコードページで書かれています。そこでは é は E9 という 1 バイトですが、UTF-8 では é は C3 A9 で、単独の E9 はテキストではありません。ページが読むのは UTF-8 と UTF-16 で、古いコードページは読まないので、どれが意図されていたかを推測する代わりに、そうしたバイト列をそれぞれ U+FFFD として表示し、最初のものがどこにあるかを伝えます。それでも「ダウンロード」は、バイトを元のままで渡します。
xxd や hexdump -C の出力を貼り付けられますか?
はい。hexdump -C の形 — 「16 進ダンプ」スタイルが書くのもこの形です — と、xxd がオプションなしで出力する形を貼り付けられます。テキストの列は脇に置かれ、どのオフセットもバイトとしては読まれず、* の行は埋め戻され、2 つの形のどちらとして読んだかを知らせが伝えます。前のバイトから導けないオフセットがあると、行どうしがもう食い違っているので、読み取りはその行で止まります。xxd -p の素の 16 進数も、ほかの 16 進数と同じように、知らせなしで読まれます。
16 進数の大文字と小文字で違いはありますか?
バイトにとっては違いはありません。4A と 4a は同じバイト、J です。ページは「小文字」を選ばない限り大文字で書き、その選択は 16 進ダンプのバイトにもオフセットにも及びます。読み取りでは、どちらでも、同じ貼り付けの中で混在していても読めます。
16 進ダンプからファイルを取り戻すには?
「16 進数からテキスト」と、UTF-8 か 2 つの UTF-16 のどちらかを選び、ダンプか素の 16 進数を貼り付けて「ダウンロード」を押してください。保存されるファイル bytes.bin には、貼り付けたものから読み取ったバイトが、テキストかどうかにかかわらずそのまま入るので、xxd -r と同じ仕事をします。元の名前に付け直してください。
本番のデータベースやログの 16 進数を貼り付けても安全ですか?
はい、変換に関して言えば安全です。変換はどちらの方向に動いても、あなた自身の端末で行われます。貼り付けた 16 進数も、それから得られるテキストも、「ダウンロード」が保存するファイルも、どこにも送られません。

関連するツール

  • テキスト / 2 進数変換

    2 進数はバイトを 8 ビットそのままで書くので、UTF-8 のパターンが読み取れます。é はこのページでは C3 A9、あちらでは 11000011 10101001 で、文字が 2 バイトなので 1 バイト目は 110 で始まり、その続きなので 2 バイト目は 10 で始まります。このページでも 2 進数を選べますが、あちらのページは 2 進数で開きます。

  • Unicode 文字インスペクター

    文字列がどの文字でできているかを正確に見る。

  • 基数変換ツール

    このページで 255 と入力すると、文字ごとに 1 バイトずつ、32 35 35 の 3 バイトになります。あちらのページは 255 を数として読み、値そのものを変換するので、16 進数では ff になります。

  • Base64

    Base64 のエンコードとデコード — UTF-8 完全対応。