Base64 をファイルにデコードする方法
- Base64 または data URI に文字列を貼り付けます。標準の Base64 も URLセーフ Base64 も受け付け、パディング、改行、引用符の有無も問いません。data URI 全体でも、それを含むテキストでも使えます。CSS の
url("data:…")、HTML のsrc="data:…"、Markdown の画像などです。ファイルに入った長い文字列は、.txt ファイルを開く を使うか、入力欄にドロップしてください。 - 入力欄の下のステータス行を確認します。入力が有効か、どのバリアント(標準か Base64URL)か、デコード後のサイズ、検出 された形式が表示されます。data URI の場合は 宣言 された形式も表示されます。
- プレビューとその下の 3 つの項目を確認します。ファイル名、拡張子、MIME タイプ は判別結果から入力されます。そこに入力した内容は クリア を押すまで保持されます。
- ファイルをダウンロード を押すか、data URI としてコピー で
data:<MIME type>;base64,…形式の文字列として取得します。
サンプル はクリックするたびに別のテストファイルを読み込みます。PNG、PDF、ZIP、WAV、DOCX、JSON、gzip、SVG です。Base64 の入ったテキストファイルではなく PDF のようなすでにバイナリのファイルをドロップすると、ツールがそのことを知らせ、逆方向に変換する ファイルを Base64 に変換 へのリンクを表示します。
ファイルが application/octet-stream になる理由
application/octet-stream は「何かのバイト列、形式は不明」という意味です。これが Base64 の前に付くのには、ありふれた理由があります。Chrome の FileReader.readAsDataURL() は、ブラウザが形式を知らないファイルに対して data:application/octet-stream;base64, を生成します。バイト列は保存しても形式は保存しないストレージやエクスポートの仕組みは、すべてをそのラベルにします。添付ファイルをすべて octet-stream と宣言するだけの API もあります。すると、ラベルに頼るビューアはファイルの表示を拒否し、ダウンロードしても役に立つ拡張子が付きません。
それでも、たいていはバイト列そのものから形式がわかります。ほとんどの形式は決まったシグネチャで始まり、ツールはそのうち 60 種類以上を確認します。いくつかのシグネチャは複数の形式で共通なので、その場合はファイルのさらに奥を調べます。
| 先頭のバイト | Base64 の先頭 | 候補 | 見分け方 |
|---|---|---|---|
PK 03 04 | UEsDB | ZIP、DOCX、XLSX、PPTX、EPUB、ODT、ODS、JAR、APK | エントリ名:word/、xl/、ppt/、mimetype エントリ、AndroidManifest.xml、META-INF/MANIFEST.MF |
RIFF | UklGR | WebP、WAV、AVI | 8 バイト目からの 4 文字 |
4 バイト目に ftyp | AAAA(例:AAAAIGZ0eXB) | MP4、M4A、MOV、3GP、HEIC、AVIF | 8~11 バイト目のブランド |
OggS | T2dnUw | Ogg Vorbis、Opus、Theora 動画 | 最初のページにあるコーデックヘッダー |
1A 45 DF A3 | GkXfo | WebM、MKV | webm ドキュメントタイプ |
D0 CF 11 E0 | 0M8R4KGxGuE | DOC、XLS、PPT、Outlook MSG、パスワード保護された Office ファイル | 見分けられません。「DOC/XLS/MSG (OLE)」と表示します |
シグネチャの一覧は よく見る Base64 の接頭辞 にあります。
data URI が宣言する形式と内容が食い違う場合は、「data URI では application/octet-stream とされていますが、内容は PDF のようです。」のような注意書きが表示され、判別した形式が使われます。宣言された形式が優先されるのは、判別の確度が低い場合、つまりバイト列がプレーンテキストや不明なバイナリに見える場合だけです。
Base64 の中の Base64、URL エンコード、gzip
複数のシステムを経由したデータは、何重にも包まれていることがよくあります。デコード後、ツールは結果がさらに別の層かどうかを確認し、もう一度デコード を表示します。
| 注意書き | 何が起きたか |
|---|---|
| 「デコード結果自体が Base64 テキストです(中身:PDF)。」 | 二重にエンコードされています。たいていは 2 つの層のコードがそれぞれ「念のため」にエンコードしたものです |
| 「デコード結果は URL エンコードされた Base64 です」 | Base64 が URL 用にパーセントエンコード(%2B、%2F、%3D)された後、再びエンコードされています |
| 「デコード結果は data: URI です。」 | ペイロードではなく data:… の文字列全体がエンコードされています |
| 「データは gzip で圧縮されています:展開後 817 B(PDF)。」 | サイズを抑えるためにエンコード前に圧縮されています。ログやメッセージキューでよく見られ、zlib も認識します |
もう一度デコード は内側の層を入力欄に入れてデコードし、戻る で 1 段ずつ外に戻れます。履歴は最大 20 段まで記憶します。gzip と zlib の注意書きは、ツールが実際にデータを展開できた後にだけ表示され、対象は 16 MB までの結果です。gzip のプレビューには、ヘッダーに保存された元のファイル名と更新日時も表示され、展開結果を保存 で中身を保存できます。テキストのペイロードなら、gzip Base64 デコーダー のほうが直接的です。
正しい拡張子で保存する
Windows と macOS は拡張子で開くプログラムを決めるので、decoded.bin として保存した PDF は、バイトがすべて正しくても壊れているように見えます。拡張子 と MIME タイプ の項目は、自分で入力するまで判別結果に従います。
- ファイル名は、data URI の
name=やfilename=パラメータ、または開いたテキストファイルの名前から.txtや.b64の末尾を除いたものになります。report.pdf.b64.txtはreport.pdfとして保存されます。 - スプレッドシートだと分かっている OLE ファイルなら、拡張子 に
xlsと入力してください。ツールは DOC、XLS、MSG を区別できません。 - 入力した MIME タイプ に合わせて、プレビューもその種類で描画し直されます。ツールが Binary と表示しても音声だと思われる場合は、
audio/oggと入力すると音声プレーヤーで試します。 - MIME タイプが影響するのは、ダウンロードと data URI としてコピー だけです。ディスク上のファイルには MIME タイプはなく、あるのはバイト列と名前だけです。
プレビューに表示される内容
どの結果にも、形式、MIME タイプ、拡張子、サイズ、SHA-256 ハッシュが表示され、16進ダンプを表示 で先頭 512 バイトを確認できます。不明なバイナリデータの場合は、最初から 16進ダンプが開いています。種類ごとの表示は次のとおりです。
| 種類 | プレビュー |
|---|---|
| 画像 | 画像とピクセルサイズ。HEIC、TIFF、JPEG XL は、多くのブラウザにデコーダーがないため、たいてい「表示できません」という注意書きになります。Base64 を画像に変換 を参照 |
| ブラウザの PDF ビューア、バージョン、ページ数、タイトル。Base64 を PDF に変換 を参照 | |
| 音声と動画 | 再生時間と動画サイズ付きのプレーヤー |
| フォント | デコードしたフォントで描画される編集可能なサンプルテキストと、ファミリー、スタイル、グリフ数 |
| ZIP、DOCX、XLSX、PPTX、EPUB | 各ファイルに 表示 と 保存 が付いたエントリ一覧。Office ファイルと電子書籍はドキュメントのテキストも表示。Base64 を ZIP に変換 を参照 |
| テキスト | 文字コード、行数、整形済みの JSON、CSV の表、XML のルート要素、サンドボックス化された HTML |
| 証明書と鍵 | 証明書デコーダー へのリンク |
コードで Base64 の MIME タイプを判別する
Base64 の 24 文字をデコードすると 18 バイトになり、一般的なシグネチャを見分けるには十分です。次のコードはブラウザでも Node.js 16 以降でも動きます。
function sniffMime(b64) {
const head = b64.replace(/^data:[^,]*,/, "").replace(/\s+/g, "").slice(0, 24)
.replace(/-/g, "+").replace(/_/g, "/");
const b = Uint8Array.from(atob(head), (c) => c.charCodeAt(0));
const str = (start, len) => String.fromCharCode(...b.subarray(start, start + len));
if (str(0, 5) === "%PDF-") return "application/pdf";
if (str(0, 8) === "\x89PNG\r\n\x1a\n") return "image/png";
if (b[0] === 0xff && b[1] === 0xd8 && b[2] === 0xff) return "image/jpeg";
if (str(0, 4) === "GIF8") return "image/gif";
if (str(0, 4) === "RIFF" && str(8, 4) === "WEBP") return "image/webp";
if (str(0, 4) === "RIFF" && str(8, 4) === "WAVE") return "audio/wav";
if (str(4, 4) === "ftyp") return "video/mp4"; // also M4A, MOV, HEIC: see bytes 8-11
if (str(0, 4) === "PK\x03\x04") return "application/zip"; // also DOCX, XLSX, PPTX
if (b[0] === 0x1f && b[1] === 0x8b) return "application/gzip";
if (str(0, 3) === "ID3" || (b[0] === 0xff && (b[1] & 0xe6) === 0xe2)) return "audio/mpeg";
return "application/octet-stream";
}
sniffMime("data:application/octet-stream;base64,JVBERi0xLjcKJeLjz9MK"); // "application/pdf"
コマンドラインでは、file が標準入力からデコード後のバイト列を読みます。
base64 -d payload.b64 | file -b --mime-type -
PDF なら application/pdf と表示されます。代わりに OpenSSL でデコードする場合は、1 行の文字列なら -A を付けてください。付けないと、行末に改行がない場合や行が長すぎる場合(OpenSSL 3.5 では 1,024 文字以上)に、openssl base64 -d は何も警告せずに空の出力を書き出します。詳しくは JavaScript での Base64 と Bash での Base64 を参照してください。
よくある質問
Base64 文字列の MIME タイプを知るには?
先頭の数バイトをデコードし、既知のファイルシグネチャと比べます。JVBERi0 は %PDF- に、iVBORw0KGgo は PNG のシグネチャにデコードされます。このページは 60 以上の形式でこれを行います。自分のコードで使うなら、このページの JavaScript 関数が一般的な形式をカバーしています。
「application/octet-stream としてファイルを表示できません」とはどういう意味ですか?
application/octet-stream は形式不明のバイト列に付けられる汎用のラベルなので、ラベルを信じるビューアには手がかりがありません。同じ文字列をここに貼り付けてください。ラベルではなく内容を調べ、拡張子と MIME タイプを自動で入力します。
形式が判別されない場合はどうすればいいですか?
その場合、プレビューには Binary と表示され、先頭 512 バイトの 16進ダンプが表示されます。形式が分かっているなら、ダウンロードの前に拡張子と MIME タイプを入力してください。MIME タイプを入れるとプレビューも切り替わり、たとえば audio/ogg ならバイト列の再生を試みます。
どのくらいの大きさのファイルまでデコードできますか?
固定の上限はなく、端末のメモリ次第です。Base64 がおよそ 50 MB を超えると、デコード中にページが少し止まります。また、32 MB を超えるファイルでは data URI としてコピー が無効になります。
ファイルがどこかにアップロードされることはありますか?
ありません。デコード、形式の判別、プレビューはブラウザ内で行われます。ページの Content Security Policy は、Cloudflare のページビュー計測を除いて、ページがネットワークへリクエストを送ることを防いでいます。