Введение
Ascii85, также называемый Base85, — это способ кодирования бинарных данных в текст, разработанный Полом Э. Раттером для утилиты btoa. Используя пять символов ASCII для представления четырех байтов бинарных данных (что приводит к увеличению размера закодированного файла по сравнению с исходным, при условии использования восьми бит на символ ASCII), он более эффективен, чем uuencode или Base64, которые используют четыре символа для представления трех байтов данных (и, следовательно, увеличивают размер, при условии использования восьми бит на символ ASCII). В настоящее время он в основном используется в файловых форматах Adobe PostScript и Portable Document Format, а также для кодирования патчей для бинарных файлов, применяемых в Git.
Ascii85, also called Base85, is a form of binary to text encoding developed by Paul E. Rutter for the btoa utility. By using five ASCII characters to represent four bytes of binary data (making the encoded size larger than the original, assuming eight bits per ASCII character), it is more efficient than uuencode or Base64, which use four characters to represent three bytes of data ( increase, assuming eight bits per ASCII character). Its main modern uses are in Adobe's PostScript and Portable Document Format file formats, as well as in the patch encoding for binary files used by Git.
Обзор
Основная потребность в кодировании двоичных данных в текст возникает из необходимости передавать произвольные двоичные данные по существующим протоколам связи, которые изначально разрабатывались для передачи только читаемого человеком текста на английском языке. Эти протоколы связи могут быть безопасными только для 7 бит (и в этом случае избегать определенных управляющих кодов ASCII), могут требовать переноса строки через определенные максимальные интервалы и могут не сохранять пробелы. Таким образом, для передачи данных "безопасны" только 94 печатаемых символа ASCII. Восемьдесят пять – минимальное целое значение n, при котором n⁵ ≥ 2564; следовательно, любую последовательность из 4 байтов можно закодировать как 5 символов, при условии, что доступно не менее 85 различных символов. (Пять цифр в системе счисления по основанию 85 могут представлять целые числа от 0 до 4 437 053 124 включительно, чего достаточно для представления всех 4 294 967 296 возможных последовательностей из 4 байтов.)
Кодирование
При кодировании каждая группа из 4 байтов рассматривается как 32-битное двоичное число, при этом наиболее значимый байт идет первым (Ascii85 использует порядок следования байтов big endian). Это число преобразуется, путем многократного деления на 85 и получения остатка, в 5 цифр в системе счисления по основанию 85. Затем каждая цифра (опять же, начиная со старшей) кодируется как печатаемый символ ASCII путем добавления к ней 33, что дает символы ASCII от 33 (!) до 117 (u). Поскольку данные, состоящие только из нулей, встречаются довольно часто, для сжатия данных делается исключение: группа, состоящая только из нулей, кодируется одним символом z вместо ! !!!!. Группы символов, которые при декодировании дают значение больше 232 − 1 (кодируются как s8W !), вызовут ошибку декодирования, как и символы z, находящиеся не в начале группы. Пробелы между символами игнорируются и могут располагаться в любом месте для соблюдения ограничений на длину строки.
Ограничения
Оригинальная спецификация допускает кодирование только потока, размер которого кратен 4 байтам. Закодированные данные могут содержать символы, имеющие специальное значение во многих языках программирования и в некоторых текстовых протоколах, такие как знак меньше <, обратная косая черта \, и одинарные и двойные кавычки ' и ". Другие кодировки на основе 85, такие как Z85, разработаны для безопасного использования в исходном коде.
версия btoa
Оригинальная программа btoa всегда кодировала полные группы (дополняя исходные данные при необходимости), с префиксной строкой "xbtoa Begin" и суффиксной строкой "xbtoa End", за которыми следовали оригинальная длина файла (в десятичном и шестнадцатеричном формате) и три 32-битные контрольные суммы. Декодеру необходимо использовать длину файла, чтобы определить, какая часть группы является дополнением. Первоначальное предложение по кодированию btoa использовало алфавит кодирования, начинающийся с символа пробела ASCII и заканчивающийся символом "t" включительно, но он был заменен алфавитом кодирования от "!" до "u", чтобы избежать "проблем с некоторыми почтовыми клиентами (удаление конечных пробелов)". Эта программа также ввела специальную короткую форму "z" для группы, состоящей только из нулей. В версии 4.2 было добавлено исключение "y" для группы, состоящей только из символов пробела ASCII (0x20202020).
Версия ZMODEM
"Кодировка ZMODEM Pack 7" кодирует группы из 4 октетов в группы из 5 печатаемых символов ASCII, подобно, или, возможно, тем же способом, что и Ascii85. Когда программа ZMODEM отправляет предварительно сжатые 8-битные файлы данных по 7-битным каналам, она использует "кодировку ZMODEM Pack 7".
Версия Adobe
Adobe приняла базовое кодирование btoa, но с небольшими изменениями, и назвала его Ascii85. Используются символы ASCII от 33 (!) до 117 (u) включительно (для представления цифр системы с основанием 85 от 0 до 84), а также буква z (в качестве особого случая для представления 32-битного значения 0), при этом пробельные символы игнорируются. Adobe использует разделитель "~>" для обозначения конца строки, закодированной в Ascii85, и представляет длину путем усечения последней группы: если последний блок исходных байтов содержит менее 4 байтов, блок дополняется до 3 нулевых байтов перед кодированием. После кодирования с конца выходной строки удаляется столько же байтов, сколько было добавлено в качестве дополнения. При декодировании применяется обратное: последний блок дополняется до 5 байтов символом Ascii85 u, и столько же байтов, сколько было добавлено в качестве дополнения, отбрасывается с конца выходной строки (см. пример). Дополнение не является произвольным. Преобразование из двоичного представления в систему с основанием 64 лишь перегруппировывает биты, не изменяя их и их порядок (старший бит в двоичном представлении не влияет на младшие биты в представлении с основанием 64). При преобразовании двоичного числа в систему с основанием 85 (85 не является степенью двойки) старшие биты влияют на младшие цифры системы с основанием 85 и наоборот. Дополнение двоичного представления снизу (нулевыми битами) при кодировании и дополнение значения в системе с основанием 85 сверху (символами u) при декодировании гарантирует сохранение старших битов (нулевое дополнение в двоичном представлении предоставляет достаточно места, чтобы небольшое приращение было учтено и не произошло переноса в старшие биты). В закодированных блоках Ascii85 пробелы и символы переноса строки могут присутствовать в любом месте, в том числе в середине блока из 5 символов, но они должны игнорироваться без выдачи ошибок. Спецификация Adobe не поддерживает исключение y.
Совместимость
Кодировка Ascii85 совместима с 7-битными и 8-битными MIME, при этом имеет меньший объем служебной информации, чем Base64. Одной из потенциальных проблем совместимости Ascii85 является то, что некоторые из используемых ею символов имеют особое значение в языках разметки, таких как XML или SGML. Для включения данных Ascii85 в эти документы может потребоваться экранирование кавычек, угловых скобок и амперсандов.
Версия RFC 1924
Опубликован 1 апреля 1996 года, информационная статья: "A Compact Representation of IPv6 Addresses" Роберта Элца предлагает кодирование IPv6-адресов в системе с основанием 85. Это отличается от описанной выше схемы тем, что он предлагает другой набор из 85 символов ASCII и предлагает выполнять все арифметические операции над 128-битным числом, преобразуя его в одно 20-значное число в системе с основанием 85 (внутренние пробелы не допускаются), а не разбивать его на четыре 32-битные группы. Предлагаемый набор символов, в порядке следования: 0–9, A–Z, a–z, а затем 23 символа !#$%& *+ ;<=>? @^ `{|}~. Наибольший представляемый адрес, 2<sup>128</sup>–1 = 74×85<sup>19</sup> + 53×85<sup>18</sup> + 5×85<sup>17</sup> + …, будет закодирован как =r54lj&NUUO~Hi%c2ym0. Этот набор символов исключает символы "',./:[\]", что делает его подходящим для использования в строках JSON (где " и \ потребовали бы экранирования). Однако для протоколов на основе SGML, в частности XML, экранирование строк может по-прежнему потребоваться (для символов <, > и &).