Protobuf JSON 変換・デコード

Protobuf のバイナリを JSON に変換・デコード。.proto なしでも読めます。16 進・Base64・gRPC フレームに対応し、int64 や Timestamp は ProtoJSON どおりに出力。JSON からのエンコードも可能。

  • ブラウザ内で処理
  • データはブラウザ外に出ません
  • 無料 · 登録不要
「バイナリ → JSON」は Protobuf のバイト列をデコードします。「JSON → バイナリ」は ProtoJSON をバイト列に戻し、.proto スキーマとメッセージ型が必要です。「サンプル JSON」は選んだ型の各フィールドを 1 回ずつ、仮の値で出力します。どのモードも入力と同時に出力を更新します。JSON 欄が空のまま「JSON → バイナリ」に切り替えると、バイト列をデコードした JSON が入ります。
バイト列をどのメッセージとしてデコードするか、JSON をどのメッセージとしてエンコードするかを選びます。一覧には .proto ファイルの型が並び、ほかの型からフィールドとして使われていない最初の型(多くはトップレベルのメッセージ)が最初から選ばれます。「スキーマなし(raw デコード)」は「バイナリ → JSON」だけにあり、名前なしでワイヤ形式を読みます。
「自動」は 16 進、Base64、エスケープ文字列、バイト列を見分け、どの形式で読んだかをステータスに表示します。16 進としても Base64 としても正しい文字列は 16 進として読み、補足に表示します。違う場合はここで Base64 を選んでください。 「自動」は、入力がフレームのフラグ(00、01、80、81)で始まり、5 バイトのヘッダーが入力全体をちょうど区切るときに gRPC フレームを外します。メッセージが複数あれば JSON 配列で出力し、gRPC-Web の trailers は補足に表示し、圧縮フラグ付きのフレームは gzip で展開します。ほかの圧縮方式には対応していません。「あり」はフレームが壊れているとエラーにします。「なし」はすべてのバイトをメッセージとして読みます。 「lowerCamelCase」は各フィールドの ProtoJSON 名を出力します。json_name オプションがあればその名前、なければフィールド名を lowerCamelCase にしたものです。「.proto のまま」はスキーマに書かれた名前で出力します。「JSON → バイナリ」はこの設定に関係なく、どちらの名前も受け付けます。 ProtoJSON では、存在情報を持たないフィールド(proto3 の通常のフィールド)がデフォルト値(0、空文字列、false、enum の最初の値)のとき出力しません。空の repeated と map も出力しません。オンにするとこれらも出力します。存在情報を持つフィールド(optional、oneof、メッセージ型)は、バイト列で設定されているときだけ出力します。 スキーマなしでデコードしたときの表示方法です。「JSON」は長さ付きの値を、読める文字列なら文字列、メッセージとして読めるなら入れ子のオブジェクト、どちらでもなければ base64 で表示します。「JSON(ほかの解釈も表示)」は、各数値を同じワイヤタイプのほかの型(sint64、sfixed64、float、double など)として読んだ値も表示します。「protoc --decode_raw」は protoc と同じテキストを出力し、入れ子のメッセージを優先します。 オフ:メッセージ型にないキーが JSON にあると、行と列、似た名前のフィールドがあればその候補を示してエンコードを止めます。オン:そのキーを飛ばして補足に一覧表示し、スキーマにない enum 名も飛ばします。

16 進(スペース、改行、コロン、0x 付きでも可)、Base64(標準・URL セーフ、パディングの有無は問わず、data: URL も可)、エスケープ文字列(Python のバイト列リテラルや protoc の 8 進エスケープ)、-128〜255 のバイト値の列を貼り付けられます。入力と同時にデコードします。「ファイルを開く」か、欄へのドロップで、2 MB までのバイナリファイルを 16 進として読み込みます。
選んだメッセージ型の ProtoJSON です。入力と同時にエンコードします。キーはフィールドの JSON 名でも .proto の名前でもかまいません。整数は数値でも文字列でも、enum は名前でも数値でも書け、bytes は Base64 です。エラーは行と列を示します。
フィールド名のもとになる .proto のソースです。「バイナリ → JSON」では省略でき、その場合はフィールド番号で表示します。ほかの 2 つのモードでは必要です。import 先のファイルは「.proto を追加」で入れるか、欄にドロップしてください。google/protobuf の Well-Known Types(any、duration、empty、field_mask、struct、timestamp、wrappers)は組み込み済みです。コンパイル済みの descriptor set は読み込めず、descriptor.proto を拡張するカスタムオプションは無視します。
出力
  
例・詳しい説明・よくある質問 実際の出力つきの例、ほかのツールとの違い、よくある質問。

例:日本語の店舗データ

次の店舗マスタを例にします。

syntax = "proto3";

package shop.v1;

message Store {
  string name = 1;
  string prefecture = 2;
  string postal_code = 3;
  repeated string tags = 4;
}

protoc --encode で作った 54 バイトのデータです。日本語は UTF-8 なので 1 文字 3 バイトになり、「渋」は e6 b8 8b です。

0a 0c e6 b8 8b e8 b0 b7 e6 9c ac e5 ba 97 12 09 e6 9d b1 e4 ba ac e9 83 bd 1a 08 31 35 30 2d 30 30 30 32 22 0f e9 a7 90 e8 bb 8a e5 a0 b4 e3 81 82 e3 82 8a

shop.v1.Store としてデコードすると、こうなります。

{
  "name": "渋谷本店",
  "prefecture": "東京都",
  "postalCode": "150-0002",
  "tags": [
    "駐車場あり"
  ]
}

postal_code が postalCode になるのは、ProtoJSON の仕様でフィールド名を lowerCamelCase に変えるためです。.proto の名前のまま欲しいときは「フィールド名:.proto のまま」を選びます。

例:スキーマがないとき

スキーマ欄を空にして raw 表示を「JSON」にすると、同じバイト列は番号付きで読めます。

{
  "1": "渋谷本店",
  "2": "東京都",
  "3": "150-0002",
  "4": "駐車場あり"
}

長さ付きの値のうち、UTF-8 として読めて制御文字を含まないものは文字列として出します。「protoc —decode_raw」表示に切り替えると protoc --decode_raw と同じ出力になり、日本語は \346\270\213 のような 8 進エスケープになります。protoc は入れ子のメッセージとして読めるものを優先するので、hi のような短い ASCII 文字列が 1 { 13: 105 } と表示されることもあります。

例:JSON からバイナリへ、全角文字の混入

日本語入力のまま JSON を書くと、全角のコロンや空白が紛れ込みがちです。

{"name": "渋谷本店",
 "prefecture": "東京都"}

「JSON → バイナリ」では、位置を示してエラーにします。

JSON 2 行 14 列:「:」は予期しない文字です。

全角スペース(U+3000)も同じく、その位置でエラーになります。直した JSON を出力「エスケープ文字列」でエンコードすると、Python でそのまま使えるバイト列リテラルになります。

b'\n\x0c\xe6\xb8\x8b\xe8\xb0\xb7\xe6\x9c\xac\xe5\xba\x97\x1a\x08150-0002'

キーは postalCode でも postal_code でも受け付けます。enum は名前でも番号でもよく、int64 は文字列でも数値でも構いません。出力は 16 進・Base64・C の配列も選べ、gRPC フレームを付けたり .bin として保存したりできます。

ほかのツールとの違い

2026-10-02 に、英語版ページの注文データ(Timestamp と 2^53 を超える int64 を含む)で試しました。Bing で「protobuf デコード」の上位に出る serenetia.com の Protobuf Decoder は pawitp の Protobuf Decoder と同じもので、スキーマなしで読み、gRPC のヘッダーも外し、uint・sint・double の読み方を並べて表示しますが、.proto は使えません。codertools.net(日本語版あり)と egohero.com は .proto を使えますが、import "google/protobuf/timestamp.proto" を含むと egohero は「no such Type or Enum ‘google.protobuf.Timestamp’」で止まり、codertools はメッセージ型の一覧が空になります。Timestamp を外すと、どちらも order_id を "9007199254740992"(実際より 1 小さい)と出力し、名前は snake_case のままでした。どのツールも入力をサーバーに送っていませんでした。

制限

  • 読み込めるのは .proto のソースだけです。protoc --descriptor_set_out で作ったディスクリプタやテキスト形式のメッセージは読めません。組み込みの import は any・duration・empty・field_mask・struct・timestamp・wrappers で、google/api/annotations.proto などから型を使う場合は追加が必要です。descriptor.proto を拡張するカスタムオプションは無視します。オプションはバイト列に影響しないためです。
  • 未知のフィールドは JSON に入りません。 補足に番号・ワイヤタイプ・バイト位置を示し、未知のフィールドなしでデコードできる型も挙げます。
  • 型を間違えてもデコードが通ることがあります。 バイト列に型名は入っていないため、補足の未知フィールドの件数を確かめてください。
  • 入れ子は 100 段まで、開けるファイルは 2 MB までです。圧縮フレームは gzip だけ展開します。
  • proto2 と editions 2023/2024 のグループ、required、closed enum、拡張("[pkg.ext]")、フィールドの存在、packed と expanded、delimited に対応します。proto3 の string が UTF-8 として正しくないときは、バイト位置付きのエラーになります。バイナリは bytes に入れてください。

関連ツール:キャプチャは HAR ファイル解析、ペイロードの変換は Base64 エンコード / デコード、JSON の検証は JSON Schema バリデーターで。

FAQ

.proto ファイルがなくてもデコードできますか?

できます。スキーマ欄を空にすると protoc --decode_raw と同じ方法で読み、フィールド番号・数値・文字列・入れ子のメッセージを表示します。フィールド名、enum 名、符号付きや 64 ビットの型、Timestamp などの Well-Known Types はバイト列に含まれないため、.proto が必要です。

int64 が文字列で出力されるのはなぜですか?

ProtoJSON の仕様で、int64・uint64・sint64・fixed64・sfixed64 は 10 進の文字列と決まっています。JavaScript は JSON の数値を double として読むので、2^53 を超えると下の桁が変わります。このツールは 64 ビットのフィールドを BigInt で読むため、桁は失われません。

JSON にフィールドが出てこないのはなぜですか?

ProtoJSON では、proto3 の通常のフィールドがデフォルト値(0、空文字列、false、enum の最初の値)のとき出力しません。「デフォルト値のフィールドも出力」をオンにすると表示されます。スキーマにない番号のフィールドは ProtoJSON に書けないため、「補足」にバイト位置付きで一覧表示します。

gRPC のキャプチャはそのまま貼れますか?

貼れます。gRPC フレームが「自動」のとき、各メッセージ先頭の 5 バイト(フラグと長さ)を外してから順にデコードします。gRPC-Web の trailers は補足に表示し、圧縮フラグ 01 のフレームは gzip で展開します。

データはアップロードされますか?

されません。解析・デコード・エンコードはすべてブラウザ内で行います。保存するのはオプションの選択だけで、スキーマ・バイト列・JSON は保存しません。