Как кодировать и декодировать Ascii85
- Введите или вставьте текст в поле Ввод · Текст. Ascii85 появится в поле Результат · Ascii85 (Adobe).
- Под результатом отметьте Добавить разделители <~ ~>, если нужна обёртка PostScript/PDF, и снимите z для нулевых групп, если ваш декодер не понимает это сокращение.
- Чтобы взять другой алфавит Base85, выберите в поле В вариант Base85 (Git / Python b85), Z85 (ZeroMQ) или RFC 1924 (IPv6 Base85).
- Для декодирования нажмите Ascii85 (Adobe) → Текст в переключателе направления. Декодер принимает разделители
<~ ~>,z,yи любые пробельные символы, так что данные с переносами строк из файла можно вставлять как есть. - Если результат двоичный, выберите в поле В вариант Hex или нажмите Сохранить байты.
Как работает Ascii85
Ascii85 берёт по 4 байта, читает их как одно 32-битное число в big-endian и записывает его пятью цифрами в системе счисления по основанию 85. Каждая цифра записывается символом от ! (значение 0) до u (значение 84). Пять символов на четыре байта дают 25% накладных расходов против 33% у Base64.
Классический пример – Man (с пробелом на конце): байты 4d 61 6e 20 превращаются в 9jqo^. Когда последняя группа неполная, кодировщик дополняет её нулевыми байтами и пишет только n + 1 символов для n байтов, поэтому Hello (5 байтов) превращается в 87cURDZ: пять символов для Hell и два для o.
Два сокращения укорачивают частые шаблоны. z заменяет группу из четырёх нулевых байтов, то есть !!!!! целиком. y в варианте btoa заменяет четыре пробела. Этот декодер читает оба, а кодировщик пишет z (это можно отключить), но никогда не пишет y.
Сравнение вариантов Base85
| Вариант | Алфавит | Hello | Где используется |
|---|---|---|---|
| Ascii85 (Adobe) | от ! до u в порядке ASCII | 87cURDZ | PostScript, PDF /ASCII85Decode |
| Base85 (Git / Python) | 0-9 A-Z a-z !#$%&()*+-;<=>?@^_`{|}~ | NM&qnZv | Бинарные патчи Git, base64.b85encode в Python |
| Z85 | 0-9 a-z A-Z .-:+=^!/*?&<>()[]{}@%$# | nm=QNzV | Ключи ZeroMQ и CurveZMQ, см. Z85 |
| RFC 1924 | Тот же, что у Git | 4)+k&C#VzJ4br>0wv%Yp для одного IPv6-адреса | IPv6-адреса, в шутку |
Алфавиты Git и RFC 1924 совпадают, но RFC 1924 считает весь 16-байтовый адрес одним 128-битным числом, а не четырьмя группами по 4 байта. RFC 1924 опубликован 1 апреля 1996 года и предлагает записывать 1080::8:800:200c:417a как 4)+k&C#VzJ4br>0wv%Yp. Конвертер воспроизводит это, если выбрать в поле Из вариант IPv6-адрес, а в поле В – RFC 1924 (IPv6 Base85).
Ascii85 в PDF и PostScript
Ascii85 появился в PostScript Level 2, чтобы встраивать двоичные данные, например картинки и шрифты, в текстовый файл. Данные заключаются в <~ … ~>. В PDF поток с /Filter /ASCII85Decode содержит ту же кодировку и заканчивается на ~>. Декодер на этой странице находит концевой маркер и с открывающим <~, и без него.
Ascii85 часто оказывается внешним фильтром цепочки, например /Filter [/ASCII85Decode /FlateDecode]. Тогда после декодирования Ascii85 получаются сжатые zlib байты, а не читаемое содержимое.
Git использует Base85 иначе. В GIT binary patch каждая строка начинается с одного символа длины (A–Z для 1–26 байтов, a–z для 27–52), за которым идёт Base85 от сжатых zlib данных. Перед декодированием уберите этот первый символ из каждой строки, а затем распакуйте результат.
Ascii85 и Base85 в Python
В стандартной библиотеке есть оба алфавита:
import base64
base64.a85encode(b"Hello") # b'87cURDZ'
base64.a85encode(b"Hello", adobe=True) # b'<~87cURDZ~>'
base64.a85encode(b" ", foldspaces=True) # b'y'
base64.b85encode(b"Hello") # b'NM&qnZv'
base64.a85decode(b"<~9jqo^~>", adobe=True) # b'Man '
Чтобы a85decode принял разделители, нужен adobe=True. Остальные рецепты ищите на странице про Python.
Частые проблемы
- «
"z"в позиции … допустим только между группами из 5 символов».zстоит внутри группы. Данные повреждены или это не Ascii85: в Z85 и Base85 из Gitzслужит обычной цифрой. - «группа, начинающаяся в позиции …, выходит за допустимый диапазон». Пять символов кодируют значение больше 2^32 − 1. Так бывает, когда Base85 из Git или Z85 декодируют как Ascii85; смените Из.
- Неожиданный символ вроде
v,{или|. Всё, что послеu, кроме сокращенийyиz, лежит за пределами алфавита Ascii85, и это ещё один признак другого варианта. - В конце результата лишние нулевые байты. Ваш кодировщик дополнил последнюю группу и записал все 5 символов. Ascii85 пишет n + 1 символов для последней группы из n байтов.
Вопросы и ответы
Чем Base85 отличается от Ascii85?
Base85 обозначает общую идею: записывать 4 байта пятью символами из набора в 85 символов. Ascii85 – вариант Adobe с символами от ! до u, сокращением z и разделителями <~ ~>. Git, b85encode в Python, Z85 и RFC 1924 используют ту же арифметику с другими алфавитами.
Что означает z в Ascii85?
Один z заменяет четыре нулевых байта, которые иначе записались бы как !!!!!. Он допустим только там, где начиналась бы полная группа из 5 символов; z внутри группы вызывает ошибку.
Как декодировать Ascii85 из PDF?
Скопируйте данные потока между stream и endstream вплоть до ~> включительно и вставьте их, выбрав направление Ascii85 (Adobe) → Текст. Если у потока указан ещё и /FlateDecode, в результате будут данные zlib: выберите в В вариант Base64 и распакуйте его декодером gzip и zlib.
Base85 лучше Base64?
Он примерно на 6% короче: 25% накладных расходов против 33%. Но в его алфавитах, в зависимости от варианта, есть кавычки, обратный слеш или < и &, поэтому в JSON, XML или shell его приходится экранировать, а Base64 – нет. Используйте его там, где эти символы безопасны.