Инструменты разработчика · Кодер и декодер Base64
Почему вставленный Base64 не декодируется: переносы строк, переводы строк и умные кавычки
· Почему это важно
base64 кодирование
Base64 редко ломается при транспортировке; он ломается в буфере обмена. В этом посте перечислены ошибки копирования и вставки, которые приводят к ошибкам недопустимых символов и длины, а также способы быстрого обнаружения каждой из них.
Ключ, который работал в терминале и не работал в браузере — один невидимый символ и двухчасовой поиск
Инженер скопировал ключ API из терминала, чтобы протестировать его в сценарии. Ключ работал нормально в терминале, но при вставке в инструмент браузера произошел сбой из-за недопустимого символа. Через два часа, просматривая код, конфигурацию и документацию, они обнаружили один невидимый символ. Новая строка в конце ключа, добавленная с помощью echo или скопированная из строки приглашения терминала, стала дополнительным символом, который сломал декодер Base64. Ключ был правильным; буфера обмена не было. Данные Base64 надежны при передаче в электронном виде, контрольной сумме и проверке. Он ломается почти исключительно при копировании и вставке вручную.
Перенос строк в терминалах, конечные символы новой строки в выводе команды, интеллектуальная замена кавычек в редакторах форматированного текста и скрытые символы Юникода при копировании и вставке между различными приложениями — все это приводит к ошибкам, которые выглядят так, будто Base64 не работает, хотя реальная проблема заключается в том, как оно было скопировано. В этом посте перечислены наиболее распространенные неисправности и показано, как быстро обнаружить и исправить каждую из них. Алфавит Base64 состоит из прописных и строчных букв, цифр, а также знаков, косой черты и символа заполнения (знака равенства). RFC 4648 специфичен: стандартная строка Base64 содержит только эти символы плюс необязательные пробелы, если строки перенесены.
Перенос строк из терминалов, почтовых клиентов и форматирование PEM — почему разрыв столбца 76 подходит для некоторых декодеров и фатален для других
Многие инструменты допускают отклонения: они принимают безопасные для URL варианты, использующие дефисы и подчеркивания вместо плюсов и косых черт, или игнорируют переводы строк. Строгий декодер, следующий за RFC, отклоняет все, что выходит за рамки ожидаемого набора символов, и завершается ошибкой с недопустимым символом. В сообщении об ошибке обычно упоминается символ, вызывающий ошибку, или отмечается, что строку вообще невозможно декодировать. При вставке Base64 из электронного письма, терминала, истории чата или отформатированного документа часто проскальзывают невидимые символы или замены символов, что приводит к сбою декодирования. Сами данные в порядке; передача из буфера обмена повредила его.
Перенос строк является наиболее распространенной причиной ошибок при вставке Base64, а также наиболее легко устраняемой. Инструменты терминала переносят вывод по 76 символов в строке или иногда 80, вставляя новую строку и переходя на следующую строку. Многие кодировщики, включая некоторые библиотеки кодирования Base64, заключают свои выходные данные в одну и ту же границу символов 76 для совместимости с электронной почтой MIME. Когда вы копируете обернутую строку Base64 из терминала, появляются символы новой строки.
Завершающие символы новой строки из инструментов echo и буфера обмена — дополнительный байт, который становится дополнительным символом.
Некоторые декодеры автоматически принимают и игнорируют символы новой строки. Другие отвергают их как недопустимые символы. Исправление состоит в том, чтобы удалить все символы новой строки и пробелы. Если строка Base64 переносится на несколько строк в терминале, выделите все строки, скопируйте их в редактор и удалите все символы новой строки.
Скопируйте полученную однострочную строку и вставьте ее в декодер. Это первое, что нужно попробовать, если паста не справилась. Завершающие символы новой строки из утилит echo и буфера обмена являются еще одной распространенной причиной. Команда echo $API_KEY печатает ключ, за которым следует новая строка, что является стандартным поведением команды. Если вы скопируете этот вывод напрямую, в копию будет включена новая строка. Некоторые терминалы добавляют дополнительную новую строку при копировании, а некоторые менеджеры буфера обмена сохраняют или дублируют новые строки. Симптом тот же, что и при переносе строк: дополнительный символ в конце строки, не принадлежащий Base64.
Смарт-кавычки, неразрывные пробелы и символы нулевой ширины — как редакторы форматированного текста переписывают обычный текст
Решение столь же простое: обрежьте концы вставленной строки в редакторе, прежде чем пытаться декодировать. Удалите начальные и конечные пробелы, а также любые символы, похожие на символы новой строки. Если строка достаточно короткая, вы можете ввести ее еще раз вручную, но для длинных ключей тщательная ручная обрезка выполняется быстрее. Умные кавычки, неразрывные пробелы и другие замены Юникода — это тонкие ловушки. Редакторы форматированного текста, такие как Word, автоматически преобразуют прямые кавычки в фигурные, преобразуют три дефиса в длинное тире и преобразуют определенные последовательности пробелов в неразрывные пробелы. Если кто-то вставляет строку Base64 в документ, а затем вы копируете ее из отформатированного документа в инструмент, такие замены происходят.
Прямая двойная кавычка ("") становится фигурной парой слева и справа, ни одна из которых не является допустимой в Base64. Неразрывный пробел (U+00A0) выглядит идентично обычному пробелу, но имеет другой код символа и не распознается всеми анализаторами как пробел. Решение состоит в том, чтобы сначала вставить его в текстовый редактор, который отменяет все форматирование. Если вы вставляете из документа Word или форматированного чата, сначала вставьте его в обычный текстовый редактор или HTML. textarea и проверьте наличие нечетных символов. Затем скопируйте текстовую версию для использования в своем инструменте.
Потеря усечения и заполнения — проверка длины по модулю-4, которая сообщает, что символы отсутствуют.
Усечение происходит, когда строка обрезается во время копирования или вставки. Очень длинная строка Base64 может превышать ограничения буфера обмена в некоторых системах или не скопироваться из-за ошибок приложения. Результатом является более короткая строка, которая является неполной. Строка Base64 после применения заполнения должна иметь длину, кратную четырем. Если длина не кратна четырем, она усекается или повреждается. В сообщении об ошибке обычно указывается, что длина строки недопустима или отсутствует символ. Исправление требует знания того, что было скопировано изначально.
Если вы можете еще раз проверить источник, скопируйте его еще раз осторожно. В противном случае усечение не подлежит восстановлению. Потеря заполнения является связанной с этим проблемой: заполнение Base64 знаками равенства иногда удаляется, чтобы сэкономить несколько байтов. Некоторые приложения не используют заполнение, а некоторые требуют его. Если строка изначально была дополнена, а заполнение потерялось, добавьте ее обратно. Строка Base64 должна иметь 0, 1 или 2 в конце знаков равенства, чтобы общая длина была кратна четырем. Если его нет и длина не кратна четырем, возможно, заполнение потеряно.
Рабочий пример: восстановление завернутой и усеченной строки — ее очистка шаг за шагом, пока она не декодируется.
Проработанный пример показывает этот ремонт шаг за шагом. Предположим, что скопированный ключ API отображается в вашем редакторе следующим образом: VGhpcyBpcyBub3QgcmVhbGx5IGEgc2VjcmV0Cg==. Начните с выявления проблем. Завершающий Cg== является нечетным; Cg — это base64 для символа новой строки (шестнадцатеричный 0A), а дополнительный == предполагает, что что-то было добавлено. Удалите завершающий Cg== и попробуйте просто VGhpcyBpcyBub3QgcmVhbGx5IGEgc2VjcmV0. Это все еще неправильно; длина — 37 символов, не кратная четырем. Снова обрежьте: VGhpcyBpcyBub3QgcmVhbGx5IGEgc2VjcmV0 (символы 35, все равно неправильно). Проверьте первоисточник. Правильная строка — VGhpcyBpcyBub3QgcmVhbGx5IGEgc2VjcmV0 (символы 32) с правильным дополнением: VGhpcyBpcyBub3QgcmVhbGx5IGEgc2VjcmV0. Добавьте его: VGhpcyBpcyBub3QgcmVhbGx5IGEgc2VjcmV0=.
Протестируйте в декодере. Это расшифровывается как Это на самом деле не секрет. На каждом этапе используйте кодировщик и декодер Base64 для проверки текущей строки, устранения выявленной проблемы и повторного тестирования до тех пор, пока она не будет декодирована. Повреждения внутри самих байтов Base64 не могут быть исправлены декодером. Если байты действительно повреждены при транспортировке, передаче или хранении, Base64 сам не сможет это обнаружить. RFC указывает допустимые символы; любой символ за пределами этого набора является задачей декодера, который необходимо перехватить. Любое повреждение байта, например, 0 становится 1 в середине символа Base64, приводит к совершенно другому коду символа и не обнаруживается только Base64.
Чего это не касается — повреждение внутри закодированных байтов, которое сам Base64 не может обнаружить.
Для обнаружения такого рода повреждений используются контрольные суммы или цифровые подписи, и они должны быть вычислены на исходных двоичных данных перед кодированием Base64. Если вы декодируете строку Base64 и результат оказывается мусором или отличается от ожидаемого, повреждение произошло до кодирования или во время передачи, а не на этапе копирования и вставки. На практике это редкость. Большинство сбоев связаны с проблемами копирования и вставки, подобными описанным выше. Систематический подход к отладке ошибок копирования-вставки Base64 заключается в последовательном тестировании каждой потенциальной проблемы. Сначала удалите все пробелы и новые строки. Затем обрежьте начальные и конечные пробелы и любые случайные символы.
Затем проверьте длину по модулю четыре и при необходимости добавьте отступы. Вставьте каждую версию в кодировщик и декодер Base64 и посмотрите, декодируется ли она. Если проверка длины не удалась, спросите, была ли строка усечена, и извлеките ее из исходного источника. Если проверка алфавита не удалась и вы видите необычные символы, найдите интеллектуальные кавычки или замены Юникода и замените их эквивалентами ASCII. Используйте онлайн-инструмент, который показывает недопустимые символы по имени, чтобы вы могли их идентифицировать и удалить. Кодер и декодер Base64 делает это для каждого недопустимого символа, точно указывая, какого символа нет в алфавите.
Вывод: проверьте длину и алфавит, прежде чем обвинять данные — как кодировщик и декодер Base64 дает вам быстрое локальное место для проверки каждого ремонта.
Используйте эту обратную связь, чтобы исправить каждый символ и продолжайте, пока строка не декодируется. Предотвратить проще, чем устранять. Когда вы поймете, что вам снова понадобится строка Base64, скопируйте ее так, чтобы сохранить форматирование. Не вставляйте его в документ с форматированным текстом. Сохраните его в обычном текстовом файле или в выделенной текстовой области, не допускающей замен. Если кто-то отправляет вам строку Base64 в отформатированном сообщении, попросите его повторно отправить ее в формате кода или в виде открытого текста. Если вам необходимо скопировать из форматированного источника, сначала вставьте его в текстовый редактор и проверьте строку перед ее использованием.
Протестируйте строку в кодере и декодере Base64, как только она у вас появится, прежде чем полагаться на нее. Если это не удастся, вы можете запросить новую копию, пока исходный код все еще доступен. Если вы подождете, пока строка не устареет или не исчезнет источник, исправление усечения или повреждения станет невозможным. Кодер и декодер Base64 предоставляет вам быстрое локальное место для проверки любой строки перед ее использованием. Тестируйте как можно раньше и чаще, чтобы ошибки копирования и вставки были обнаружены немедленно.