Данные файла в кодировке base64 значение должно быть не больше 4404019 символов
Плюсы и минусы
Base64
Позволяет кодировать информацию, представленную набором байтов, используя всего 64 символа: A-Z, a-z, 0-9, /, +. В конце кодированной последовательности может содержаться несколько спецсимволов (обычно “=”).
- Позволяет представить последовательность любых байтов в печатных символах.
- В сравнении с другими Base-кодировками дает результат, который составляет только 133.(3)% от длины исходных данных.
- Регистрозависимая кодировка.
Base32
Использует только 32 символа: A-Z (или a-z), 2-7. Может содержать в конце кодированной последовательности несколько спецсимволов (по аналогии с base64).
- Последовательность любых байтов переводит в печатные символы.
- Регистронезависимая кодировка.
- Не используются цифры, слишком похожие на буквы (например, 0 похож на О, 1 на l).
- Кодированные данные составляют 160% от исходных.
ZBase32
- Человеко-ориентированный алфавит из 32 символов. Наиболее проработанная таблица символов для облегчения написания, произношения и запоминания кодированной информации. Авторы переставили наиболее удобные для человека символы на позиции, которые используются чаще всего. Как они это сделали я не знаю. Алфавит приводится ниже.
- Нет специальных символов в конце результата кодирования.
Описание алгоритма ZBase32 кодирования
Итак, имеем 32-х символьный алфавит следующего содержания:
На входе массив байтов (естественно, по 8 бит каждый), который хотелось бы перевести в символы из алфавита.
Алфавит представляет собой строку из 32-х элементов, а это означает, что каждый из его символов кодируется числом от 0 до 31 (индексы символов в строке). Как известно, любое число от 0 до 31 в бинарной системе счисления можно записать, используя 5 битов байта. Из этого следует, что если представить исходный набор байтов как единый массив битов и разбить его на кусочки по 5 битов (см. рисунок ниже), то мы получим набор координат символов из алфавита. Вот, собственно, и все.
Алгоритмы Base32 и Base64 аналогичны ZBase32, только разные алфавиты (по составу в случае с Base32, по составу и размеру в случае Base64) и размеру “отщипываемых” кусочков бит (6 бит для Base64).
Итак, я предлагаю перед тем, как начать разбиение исходных данных на кусочки по 5 бит, подготовить место куда будет записываться результат. Чтобы не задумываться об индексах в статических массивах, давайте использовать StringBuilder.
При инициализации сразу задаем размер результирующей строки (чтобы не тратить время на расширение в процессе работы алгоритма).
Теперь осталось пробежать по исходному массиву байтов и разделить его на 5-и битовые кусочки. Для удобства я предлагаю работать с группой по 5 байтов, так как это 40 бит — число, кратное длине “кусочков”. Но не забываем, что исходные данные никто для нас не подгонял, поэтому учитываем возможность недостачи.
Так как мы работаем с группой из 5 байтов, нам нужен буфер, где будет формироваться сплошной набор битов (всего 40 бит). Заведем переменную типа ulong (64 бита в нашем распоряжении) и поместим туда текущую партию байтов.
И заключительный этап — это “отщипывание” из того, что получилось, кусочков по 5 бит и формирование результата.
Возможно, в последнем примере кода с первого взгляда не все понятно, но если вы немного сосредоточитесь, то все станет на свои места.
Процесс декодирования происходит аналогично процессу кодирования, только в обратном направлении.
Если Интернет является информационной магистралью, то в случае с электронной почтой имеются ограничения. Через нее могут передаваться только небольшие данные.
Base64 в помощь
Кодирование Base64 занимает три байта, каждый из которых состоит из восьми битов, и представляет их в виде четырех печатных символов в стандарте ASCII. По сути, делается это в два шага.
Первым шагом является преобразование трех байтов в четыре числа из шести бит. Каждый символ в стандарте ASCII состоит из семи битов. Base64 использует только 6 бит (что соответствует 2 ^ 6 = 64 символам), чтобы гарантировать, что закодированные данные могут быть пригодны для печати и читаемы "по-человечески".
Ни один из специальных символов, доступных в таблице ASCII, не используется. 64 символа (отсюда и название Base64) - это 10 цифр, 26 символов в нижнем регистре, 26 символов в верхнем регистре, а также символы "+" и "/".
Например, три байта равны 155, 162 и 233, соответствующий (и пугающий) поток битов равен 100110111010001011101001, который, в свою очередь, соответствует 6-битовым значениям 38, 58, 11 и 41.
Эти цифры преобразуются в символы из таблицы ASCII на втором шаге с использованием таблицы "Base64 encoding". 6-битные значения нашего примера преобразуются в последовательность ASCII "m6Lp".
- 155 -> 10011011
- 162 -> 10100010
- 233 -> 11101001
- 100110 -> 38
- 111010 -> 58
- 001011 -> 11
- 101001 -> 41
- 38 -> m
- 58 -> 6
- 11 -> L
- 41 -> p
Этот двухэтапный процесс применяется ко всей последовательности байтов, которые закодированы. Чтобы гарантировать, что закодированные данные могут быть правильно напечатаны и не превышают ограничения почтового сервера, символы новой строки добавляются так, чтобы общая длина строк не превышала 76 символов. Символы новой строки кодируются, как и все остальные данные.
Решение
Решение состоит в том, чтобы добавить достаточно байтов со значением "0" для создания 3-байтовой группы. Два таких значения добавляются, если у нас есть один дополнительный байт данных, один добавляется для двух дополнительных байтов.
Конечно, эти искусственные завершающие "0" не могут быть закодированы, используя таблицу кодирования ниже. Они должны быть представлены 65-м символом.
При сохранении справки используется метод кодирования информации Base64. Он же выполняет роль дешифратора файла, в котором хранится заполненная ранее справка.
Если при дешифровке происходит сбой или в файле обнаруживаются недопустимые символы, то появляется данная ошибка.
Для начала убедитесь, что у вас установлена та же версия СПО Справки БК, в которой последний раз сохранялся открываемый файл. Иногда новая сборка программы не может открыть документы, сохранённые в предыдущих версиях.
Известны случаи наоборот — когда установка свежей версии решала проблему.
Если версия программы та же, но файл не открывается, первое, что делать — сохраните копию оригинального файла с декларацией! Это нужно, чтобы в случае неверного действия окончательно не потерять данные.
Попробуйте восстановить прежнюю версию файла. Если на вашем компьютере делается бекап или вы сразу после заполнения сохранили копию.
Также может помочь установка свежей версии программы на Windows 10. Есть случаи, когда на Windows 7 или XP проблема с base64 есть, а на «десятке» всё прекрасно открывается.
Если это не ваш случай, то кликните на файл правой кнопкой мыши и откройте его в текстовом редакторе. Например, в Блокноте.
Откроется окно с непонятным набором символов — это зашифрованные данные Base64. В них содержится ошибка из-за чего СПО Справки БК не могут открыть файл.
В тексте не должно быть символов кириллицы. Если их нет и написанное выше тоже не помогло — значит документ повреждён и, к сожалению, сделать ничего нельзя. Только заполнять заново.
Теоретически, можно попытаться расшифровать данные через онлайн-сервисы дешифровки Base64, как советую остальные сайты. Однако, при написании этой статьи я протестировала несколько сервисов, но ни один не сработал.
Вообще, все началось давно. Настолько давно, что вряд ли остались свидетели holy wars тех дней, когда решалось — сколько же бит должно быть в байте.
Это сейчас нам кажется само собой разумеющимся, что 1 байт = 8 бит, что в байте можно закодировать 256 различных значений. Но когда-то было совсем не так. История помнит и семибитные кодировки, и шестибитные, и даже более экзотические системы (например — ЭВМ «Сетунь», которая использовала троичную логику, то есть один троичный бит — трит мог иметь три, а не два значения, для нее было справедливо соотношение 1 трайт = 6 тритам). Но если оставить в стороне всякую экзотику, то мэйнстримом все-таки были кодировки, в которых 6, 7 или 8 бит в байте.
Шестибитная кодировка (например — BCD) позволяла закодировать в одном байте 64 различных значения, что, как казалось, было вполне достаточно для кодирования алфавитно-цифровых символов, а «лишний» седьмой бит расширял кодировку уже до 128 символов.
Однако скоро восьмибитный байт стал общепринятым.
Проблема восьмого бита
Утверждение восьмибитных кодировок как стандарта де-факто принесло много проблем. К этому моменту уже существовала определенная инфраструктура, использующая именно семибитные кодировки, и holy wars разгорелись с новой силой.
До нас они дошли в виде проблем с «обрезанием восьмого бита» в системе электронной почты. Утверждение восьмибитного байта дало 256 различных значений для одного байта, что, в свою очередь позволило уместить в одной кодовой таблице и общепринятые символы (цифры, знаки препинания, латиницу) и символы, скажем кириллицы. Казалось бы — сплошное удобство, текст можно набирать хоть русскими буквами, хоть английскими, а если нужно — и для немецких умлаутов место найдется!
Но, как всегда, дьявол крылся в деталях. Уже накопленный и работающий хард-н-софт зачастую был приспособлен для кодировок семибитных, что приводило к разнообразным проблемам.
А что было делать другим языкам, народам и кодировкам? А бинарные данные? Все равно кодировки с транслитерацией не решали фундаментальную проблему — потерю восьмого бита, потерю части информации. Так родилась кодировка (а точнее — алгоритм) Base64.
Алгоритм Base64
Идея base64 проста — обратимое кодирование, с возможностью восстановления, которое переводит все символы восьмибитной кодовой таблицы в символы, гарантированно сохраняющиеся при передаче данных в любых сетях и между любыми устройствами.
В основе алгоритма лежит сведение трех восьмерок битов (24) к четырем шестеркам (тоже 24) и представление этих шестерок в виде символов ASCII. Таким образом получается обратимое шифрование, единственным недостатком которого будет увеличивающийся при кодировании размер — в соотношении 4:3.
Пример:
Возьмем текст русский текст «АБВГД». В двоичной форме в кодировке Windows-1251 мы получим 5 байтов:
11000000
11000001
11000010
11000011
11000100
(00000000) — лишний нулевой байт нужен, чтобы общее число бит делилось на 6
Разделим эти биты на группы по 6:
110000
001100
000111
000010
Компьютеры хранят данные как поток бит. Как изображения, аудио- или видеофайлы, так и бинарные файлы могут содержать практически любую последовательность бит.
Однако мы часто используем текстовые форматы; например, веб-страницы и электронные письма должны быть в текстовом формате. Как же мы отправляем изображения по электронной почте? Как внедряем картинки на веб-страницы? Один из вариантов — поставить ссылку на реальный бинарный файл. Другой типичный подход — встроить бинарный файл непосредственно в тело письма или веб-страницы с помощью base64. Base64 — это просто стандартный текстовый формат, который можно использовать для кодирования любых бинарных данных. Если быть точным, то код base64 — всегда валидный текст ASCII (и поэтому также валидный UTF-8). Каждый байт кода base64 содержит 6 бит данных. То есть мы «теряем» примерно 2 бита на байт. Поэтому эквивалент base64 бинарного файла будет примерно на 33% больше. На практике такое увеличение размера редко становится проблемой. Насколько я знаю, приложения к электронным письмам почти всегда кодируются в base64.
При написании HTML я нашёл удобным внедрять изображения напрямую в HTML-код с помощью схемы data URI. Например, в недавней статье я таким образом закодировал файл PNG. Крупнейшие веб-сайты вроде Google постоянно используют эту схему. Небольшим недостатком становится то, что веб-страницы чуть увеличиваются в размере (что очевидно) и нельзя воспользоваться преимуществами кэширования изображений. Но зато браузер экономит один сетевой запрос.
Если вы веб-разработчик, то можете использовать Web Storage для создания базы данных для вашего приложения на клиентской стороне. Эта клиентская БД будет хранить изображения и произвольные данные, но они все должны быть закодированы в base64.
Большинство движков баз данных поддерживают бинарные данные, но некоторые требуют в какой-то момент кодирования в base64: это MongoDB, Elasticsearch, Amazon SimpleDB и Amazon DynamoDB. Вероятно, и какие-то ещё.
Base64 повсеместно используется в криптографии для обмена ключами. Форма base64 также используется для передачи произвольных данных в составе URI.
К счастью, кодирование и декодирование base64 происходят быстро. Хотя есть случаи, когда недостаточная скорость может стать проблемой. Мэтт Крейн и Джимми Лин обнаружили медленное декодирование бинарных атрибутов base64 в Amazon DynamoDB.
Насколько быстро вы можете декодировать данные base64? На последнем процессоре Intel это требует примерно двух циклов на байт (из кэша) при использовании быстрого декодера вроде того, что встроен в браузер Chrome. Этот быстрый декодер, в основном, занят обращениями к таблице. Это намного медленнее, чем копирование данных в кэше (что занимает менее 0,05 циклов на байт).
Это лучшее, что можно получить?
Несколько лет назад Альфред Клопп показал, что можно добиться гораздо лучшего результата при использовании векторных инструкций. Войцех Мула, я сам и несколько коллег (в том числе Говард и Курц) решили серьёзно пересмотреть проблему. Мула открыл веб-страничку, посвящённую этой теме.
Мы обнаружили, что можно ускорить обработку в 10 раз и использовать всего около 0,2 циклов на байт на последних процессорах Intel при использовании векторных инструкций. Это по-прежнему больше, чем копирование, но намного меньше лимита, способного когда-либо стать самым узким местом системы. Должен обратить внимание, что в эти 0,2 цикла на байт входит обработка ошибок: декодер должен декодировать и проверять входные данные (например, если найдены недопустимые символы, то декодирование отменяется).
Код для нашего исследования доступен, так что можете воспроизвести результаты. Наша статья опубликована на arXiv и принята для публикации в веб-версии ACM Transactions.
Насколько я понимаю, наши хорошие результаты интегрированы в библиотеку base64 Кломпа.
Так как же проехать на грузовике через это маленькое ущелье?
То же самое происходит, когда вы отправляете вложения по электронной почте. В процессе, известном как кодирование, двоичные данные преобразуются в текст ASCII, который можно без проблем транспортировать по электронной почте. В конце пути данные декодируются и мы получаем исходный файл.
Одним из методов кодирования данных в виде обычного текста ASCII является Base64.
Это один из способов, используемых стандартом MIME для отправки данных, отличных от обычного текста.
Читайте также: