Как декодировать Base64 в файл
- Вставьте строку в поле Base64 или data URI. Принимается и стандартный, и URL-safe Base64, с дополнением или без, с переносами строк или кавычками. Подойдёт целый data URI, а также текст, в котором он есть: CSS
url("data:…"), HTMLsrc="data:…"или картинка в Markdown. Длинную строку из файла загрузите кнопкой Открыть файл .txt или перетащите файл в поле. - Посмотрите на строку статуса под полем ввода: корректен ли ввод, какой это вариант (стандартный или Base64URL), размер после декодирования и тип в поле Определено. Для data URI показан ещё и тип в поле Заявлено.
- Проверьте превью и три поля под ним. Имя файла, Расширение и MIME-тип заполняются по результату определения. Всё, что вы впишете туда сами, сохраняется, пока вы не нажмёте Очистить.
- Нажмите Скачать файл или Скопировать как data URI, чтобы получить байты обратно в виде
data:<MIME type>;base64,….
Кнопка Пример при каждом нажатии загружает новый тестовый файл: PNG, PDF, ZIP, WAV, DOCX, JSON, gzip и SVG. Если перетащить файл, который уже двоичный, например сам PDF вместо текстового файла с его Base64, инструмент скажет об этом и даст ссылку на файл в Base64, который работает в обратную сторону.
Почему файл определяется как application/octet-stream
application/octet-stream означает «какие-то байты, тип неизвестен». Перед Base64 эта метка оказывается по вполне обычным причинам. FileReader.readAsDataURL() в Chrome выдаёт data:application/octet-stream;base64, для любого файла, тип которого браузер не знает. Системы хранения и выгрузки, которые сохраняют байты, но не тип, помечают так всё подряд. Некоторые API просто объявляют любое вложение как octet-stream. Просмотрщик, который полагается на метку, отказывается показывать файл, а при скачивании тот не получает нормального расширения.
Сами байты обычно знают, что они такое. Большинство форматов начинается с постоянной сигнатуры, и инструмент проверяет больше 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-го байта |
ftyp с 4-го байта | 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).» | Данные закодировали дважды: обычно два слоя кода, каждый из которых кодировал «на всякий случай» |
| «Декодированные данные – это URL-кодированный Base64» | Base64 закодировали в percent-encoding для URL (%2B, %2F, %3D), а потом закодировали ещё раз |
| «Декодированные данные – это data: URI.» | Кто-то закодировал всю строку data:… вместо её полезной нагрузки |
| «Данные сжаты gzip: после распаковки 817 B (PDF).» | Данные сжали перед кодированием ради экономии места, обычное дело в логах и очередях сообщений; zlib тоже распознаётся |
Декодировать ещё раз подставляет внутренний слой в поле ввода и декодирует его; Назад возвращает на шаг обратно и помнит до 20 шагов. Подсказки о gzip и zlib появляются только после того, как инструмент действительно распаковал данные, для результатов до 16 MB. Превью gzip показывает также исходное имя файла и время изменения из заголовка, а кнопка Сохранить распакованное сохраняет содержимое. Для текстовых данных удобнее декодер gzip Base64.
Как сохранить файл с правильным расширением
Windows и macOS выбирают программу по расширению, поэтому PDF, сохранённый как decoded.bin, кажется битым, хотя все байты на месте. Поля Расширение и MIME-тип следуют за результатом определения, пока вы не начнёте в них печатать:
- Имя файла берётся из параметра
name=илиfilename=в data URI либо из имени открытого текстового файла без окончания.txtили.b64:report.pdf.b64.txtсохраняется какreport.pdf. - Если вы знаете, что файл OLE на самом деле таблица, впишите
xlsв поле Расширение; различить DOC, XLS и MSG инструмент не может. - Введённый вами MIME-тип ещё и перерисовывает превью для этого типа. Если инструмент пишет Binary, а вы ждёте аудио, введите
audio/ogg, и он попробует аудиоплеер. - MIME-тип влияет только на скачивание и Скопировать как data URI. На диске от файла остаются только байты и имя.
Что показывает превью
Для каждого результата выводятся тип, MIME-тип, расширение, размер и хеш SHA-256, а кнопка Показать hex-дамп открывает первые 512 байт. Для неизвестных двоичных данных hex-дамп открыт сразу. В зависимости от типа:
| Тип | Превью |
|---|---|
| Изображения | Картинка и её размер в пикселях; для HEIC, TIFF и JPEG XL обычно появляется подсказка, что браузер не умеет их показывать: в большинстве браузеров нет декодера. См. Base64 в картинку. |
| Встроенный просмотрщик PDF браузера, версия, число страниц, заголовок. См. Base64 в PDF. | |
| Аудио и видео | Плеер с длительностью и размером видео |
| Шрифты | Редактируемый пример текста декодированным шрифтом, с семейством, начертанием и числом глифов |
| ZIP, DOCX, XLSX, PPTX, EPUB | Список элементов с кнопками Открыть и Сохранить для каждого файла, а для документов Office и электронных книг ещё и текст. См. Base64 в ZIP. |
| Текст | Кодировка, строки, отформатированный JSON, таблица для CSV, корневой элемент для XML, HTML в песочнице |
| Сертификаты и ключи | Ссылка на декодер сертификатов |
Как определить MIME-тип Base64 в коде
Двадцать четыре символа Base64 декодируются в 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, добавьте -A для строки в одну линию. Без этого флага openssl base64 -d молча ничего не выводит, если в конце строки нет перевода строки или она слишком длинная (1 024 символа и больше в OpenSSL 3.5). Подробнее в статьях Base64 в JavaScript и Base64 в Bash.
Вопросы и ответы
Как узнать MIME-тип строки Base64?
Декодируйте первые несколько байтов и сравните их с известными сигнатурами файлов: JVBERi0 декодируется в %PDF-, iVBORw0KGgo в сигнатуру PNG. Эта страница делает так для более чем 60 форматов, а функция на JavaScript ниже покрывает самые распространённые в вашем собственном коде.
Что значит «cannot display the file as application/octet-stream»?
Метку application/octet-stream ставят на байты неизвестного типа, и просмотрщику, который верит метке, не за что зацепиться. Вставьте ту же строку сюда: инструмент смотрит на содержимое, а не на метку, и сам заполняет расширение и MIME-тип.
Что делать, если тип не определился?
Тогда превью показывает Binary и hex-дамп первых 512 байт. Если вы знаете формат, впишите расширение и MIME-тип перед скачиванием; MIME-тип заодно переключает превью, так что с audio/ogg инструмент попробует воспроизвести байты.
Файл какого размера можно декодировать?
Жёсткого ограничения нет: всё упирается в память устройства. Примерно от 50 MB Base64 страница ненадолго замирает при декодировании, а Скопировать как data URI отключается для файлов больше 32 MB.
Файл куда-нибудь загружается?
Нет. Декодирование, определение типа и превью работают в браузере, а политика безопасности контента (CSP) страницы не даёт ей отправлять сетевые запросы, кроме счётчика просмотров Cloudflare.