Как кодировать и декодировать xxencode
Кодирование:
- Введите или вставьте текст в поле Ввод · Текст. Блок xxencode появится в поле Результат · xxencode.
- В поле Имя файла под результатом укажите имя, которое должен получить адресат; по умолчанию это
data.bin. - Снимите галочку строки begin/end, если нужны только строки данных.
Декодирование:
- Нажмите xxencode → Текст в переключателе направления.
- Вставьте блок. Текст перед строкой
begin, например заголовок письма или примечание, пропускается. - Прочитайте результат, для бинарных данных выберите В → Hex или нажмите Сохранить байты, чтобы скачать файл под именем из строки
begin.
Зачем появился xxencode
Алфавит uuencode включает все символы от пробела (или обратной кавычки) до _, в том числе [, ], ^, \ и !. С ними были проблемы на почтовых шлюзах между системами ASCII и EBCDIC, включая мейнфреймы IBM и сеть BITNET: у этих символов не было однозначного соответствия в EBCDIC. Файлы приходили с подменёнными символами и декодировались в мусор.
Xxencode сохраняет структуру uuencode, но меняет алфавит на 64 символа, которые конвертируются надёжно: +, -, 0–9, A–Z и a–z. Значение 0 записывается как +, 1 – как -, цифры начинаются со значения 2, а строчная z означает 63.
Uuencode и xxencode рядом
Одни и те же данные в обоих форматах, имя файла hello.txt:
| Ввод | Строка данных uuencode | Строка данных xxencode |
|---|---|---|
Cat | #0V%T | 1Eq3o |
Hello, world | ,2&5L;&\L('=O<FQD | AG4JgP4wg65RjQalY |
| 4 нулевых байта | $```````` | 2++++++++ |
Первый символ каждой строки содержит число байтов, записанное алфавитом самого формата: 3 записывается как # в uuencode и 1 в xxencode, 12 – как , и A, 4 – как $ и 2. Полная строка на 45 байт начинается с M в uuencode и с h в xxencode.
Так выглядит целый файл xxencode с текстом The quick brown fox jumps over the lazy dog. 0123456789, сохранённым как fox.txt:
begin 644 fox.txt
hJ4VZ653pOKBf647mPrRi64NjS0-eRKpkQm-jRaJm65FcNG-gMLdt64FjNmsU
8A12mAnEpBXQsCE++
+
end
Размер такой же, как у uuencode: 4 символа на 3 байта плюс символ длины и перевод строки на каждую строку, то есть примерно на 38% больше исходных данных.
Xxencode в Python
В Python нет xxencode, но binascii.b2a_uu выдаёт те же 6-битные значения, поэтому если перевести его вывод из алфавита uuencode в алфавит xxencode, получатся корректные строки xxencode вместе с символом длины:
import binascii
UU = "`" + "".join(chr(c) for c in range(33, 96))
XX = "+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
TO_XX = str.maketrans(UU, XX)
def xxencode_line(chunk: bytes) -> str:
return binascii.b2a_uu(chunk, backtick=True).decode().translate(TO_XX)
xxencode_line(b"Cat") # '1Eq3o\n'
Подавайте ей по 45 байт за раз, затем добавьте begin 644 name сверху и + и end снизу. Для декодирования переводите через str.maketrans(XX, UU) и вызывайте binascii.a2b_uu для каждой строки. О байтах и кодировках в Python подробнее на странице про Python.
Частые проблемы
- Файл, который якобы в xxencode, декодируется в мусор. Проверьте первый символ полных строк. Если это
M, файл в uuencode; используйте инструмент uuencode. - Строка декодируется не в ту длину. Символ длины изменился или потерялся, часто из-за почтового клиента, который заново перенёс строки. Xxencode не умеет восстанавливать разрезанную или склеенную строку.
- Декодированный файл обрывается. Блок был отправлен несколькими частями. Соедините их по порядку, с одной строкой
beginи однойend, и декодируйте результат.
Вопросы и ответы
Чем xxencode отличается от uuencode?
Только алфавитом. Оба записывают 3 байта четырьмя символами в строках до 45 байт с символом длины в начале, между begin и end. Uuencode использует диапазон ASCII от обратной кавычки и ! до _, xxencode – +, -, цифры и буквы.
Как понять, файл в xxencode или в uuencode?
Посмотрите на первый символ полных строк данных: M означает uuencode, h – xxencode, оба обозначают 45 байт. Строки, полные знаков препинания вроде `, # или %, выдают uuencode.
Какой программой декодировать файлы xxencode?
UUDeview понимает оба формата; в Debian и Ubuntu это пакет uudeview. uudecode из GNU sharutils читает uuencode и Base64, но не xxencode, так что здесь он не подойдёт.
Почему файл xxencode заканчивается строкой из одного +?
+ в xxencode означает 0, поэтому строка из одного + обозначает строку данных нулевой длины. Она играет ту же роль, что одинокая обратная кавычка в uuencode перед end.