uuencoding — это форма двоично-текстового кодирования , которая возникла в программах Unix uuencode и uudecode, написанных Мэри Энн Хортон в Калифорнийском университете в Беркли в 1980 году [1] для кодирования двоичных данных для передачи в системах электронной почты .
Название "uuencoding" происходит от Unix-to-Unix Copy , т. е. "Unix-to-Unix кодирование" является безопасным кодированием для передачи произвольных файлов из одной системы Unix в другую, но без гарантии, что промежуточные ссылки будут все системами Unix. Поскольку сообщение электронной почты может быть переслано через или на компьютеры с разными наборами символов или через транспорты, которые не являются 8-битными чистыми , или обрабатываться программами, которые не являются 8-битными чистыми, пересылка двоичного файла по электронной почте может привести к его повреждению. При кодировании таких данных в подмножество символов, общее для большинства наборов символов, закодированная форма таких файлов данных вряд ли будет "переведена" или повреждена, и, таким образом, будет доставлена в пункт назначения нетронутой и неизмененной. Программа uudecode отменяет эффект uuencode , воссоздавая в точности исходный двоичный файл. uuencode/decode стал популярным для отправки двоичных (и особенно сжатых) файлов по электронной почте и публикации в группах новостей Usenet и т. д.
Теперь его в значительной степени заменили MIME и yEnc . С MIME файлы, которые могли быть закодированы в формате uuencoded, передаются с кодировкой Base64 .
Файл в формате UUEncode начинается со строки заголовка следующего вида:
начать <режим> <файл><новая строка>
<mode>
это права доступа к файлу Unix в виде трех восьмеричных цифр (например, 644, 744). Обычно это имеет значение только для операционных систем типа Unix .
<file>
— имя файла, которое будет использоваться при воссоздании двоичных данных.
<newline>
обозначает символ новой строки , используемый для завершения каждой строки.
Каждая строка данных использует формат:
<символ длины><отформатированные символы><новая строка>
<length character>
символ, указывающий количество байтов данных, которые были закодированы в этой строке. Это символ ASCII , определяемый путем добавления 32 к фактическому количеству байтов, за исключением знака ударения "`" (код ASCII 96), обозначающего ноль байтов. Все строки данных, кроме последней (если длина данных не делится на 45), имеют 45 байтов закодированных данных (60 символов после кодирования). Поэтому подавляющее большинство значений длины — это "M" (32 + 45 = код ASCII 77 или "M").
<formatted characters>
являются закодированными символами. Подробнее о фактической реализации см. в разделе Механизм форматирования.
Файл заканчивается двумя строками:
`<новая строка>конец<новая строка>
Предпоследняя строка также является символом, указывающим длину строки, при этом знак ударения обозначает ноль байтов.
В качестве полного файла, UUE-кодированный вывод для простого текстового файла с именем cat.txt, содержащего только символы Cat , будет выглядеть следующим образом:
начало 644 cat.txt#0В%Т`конец
Начальная строка представляет собой стандартный заголовок uuencode; символ «#» указывает на то, что эта строка кодирует три символа; последние две строки появляются в конце всех файлов, закодированных с помощью uuencode.
Механизм uuencoding
повторяет следующее для каждых 3 байтов, кодируя их в 4 печатных символа, каждый символ представляет собой цифру в системе счисления с основанием 64 :
Если длина источника не делится на 3, то последний 4-байтовый раздел будет содержать байты заполнения, чтобы сделать его чисто делимым. Эти байты вычитаются из строки, <length character>
чтобы декодер не добавлял нежелательные символы в файл.
uudecoding
является обратным к предыдущему, вычитаем 32 из ASCII-кода каждого символа ( по модулю 64 для учета использования грависа), чтобы получить 6-битное значение, объединяем 4 6-битные группы, чтобы получить 24 бита, затем выводим 3 байта.
Процесс кодирования демонстрирует данная таблица, которая показывает вывод вышеуказанной кодировки для слова «Cat».
В следующей таблице показано преобразование десятичного значения 6-битных полей, полученных в процессе преобразования, а также соответствующий им выходной код символа ASCII и символ.
Обратите внимание, что некоторые кодировщики могут выдавать пробел (код 32) вместо апострофического ударения ("`", код 96), в то время как некоторые декодеры могут отказаться декодировать данные, содержащие пробел.
Ниже приведен пример uuencoding однострочного текстового файла. В этом примере %0D — это байтовое представление для возврата каретки , а %0A — байтовое представление для перевода строки .
Имя файла = wikipedia-url.txtСодержимое файла = http://www.wikipedia.org%0D%0A
начало 644 wikipedia-url.txt::'1T<#HO+W=W=RYW:6MI<&5D:6$N;W)G#0H``конец
Unix традиционно имеет одну ветку , где хранятся данные файла. Однако некоторые файловые системы поддерживают несколько веток, связанных с одним файлом. Например, классическая иерархическая файловая система Mac OS (HFS) поддерживала ветку данных и ветку ресурсов . Mac OS HFS+ поддерживает несколько веток, как и альтернативные потоки данных Microsoft Windows NTFS . Большинство инструментов uucoding обрабатывают только данные из первичной ветки данных, что может привести к потере информации при кодировании/декодировании (например, комментарии файлов Windows NTFS хранятся в другой ветке). Некоторые инструменты (например, классическое приложение Mac OS UUTool ) решили эту проблему, объединив разные ветки в один файл и дифференцируя их по имени файла.
Несмотря на ограниченный диапазон символов, данные в формате uuencode иногда повреждаются при прохождении через определенные компьютеры, использующие не-ASCII наборы символов, такие как EBCDIC . Одной из попыток решить эту проблему был формат xxencode, который использовал только буквенно-цифровые символы и символы плюс и минус. Сегодня более распространенным является формат Base64, который основан на той же концепции буквенно-цифровых символов -only в отличие от ASCII 32–95. Все три формата используют 6 бит (64 различных символа) для представления своих входных данных.
Base64 также может быть сгенерирован программой uuencode и имеет аналогичный формат, за исключением фактического преобразования символов:
Заголовок изменен на
begin-base64 <режим> <файл>
трейлер становится
====
и линии между ними кодируются символами, выбранными из
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
Другой альтернативой является Ascii85 , который кодирует четыре двоичных символа в пять символов ASCII. Ascii85 используется в форматах PostScript и PDF .
uuencoding берет 3 предварительно отформатированных байта и превращает их в 4, а также добавляет начальные/конечные теги, имя файла и разделители . Это добавляет не менее 33% накладных расходов по сравнению с исходным кодом, хотя это можно хотя бы в какой-то степени компенсировать, сжав файл перед его uuencoding.
Язык Python поддерживает uu-кодирование с помощью модуля codecs с кодеком «uu»:
Для Python 2 (устарел/не поддерживается с 1 января 2020 г.) :
$ python -c 'print "Cat".encode("uu")' begin 666 <data> # 0V%T end $
Для Python 3 , где модуль кодеков необходимо импортировать и использовать напрямую :
$ python3 -c "из кодеков импортировать кодирование;печать(кодирование(b'Cat', 'uu'))" b'begin 666 <данные>\n#0V%T\n \nend\n' $
Для декодирования передайте весь файл:
$ python3 -c "из кодеков импортировать декодировать;печать(декодировать(b'begin 666 <data>\n#0V%T\n \nend\n', 'uu'))" b'Cat'
Язык Perl изначально поддерживает uu-кодирование с помощью операторов pack() и unpack() со строкой формата «u»:
$ perl -e 'print pack("u","Cat")' # 0V%T
Декодирование base64 с помощью unpack также можно выполнить путем перевода символов:
$ perl -e 'print unpack("u","#0V%T")' Кот
Для создания правильно сформированных файлов в формате UUEncode вам необходимо использовать модули [3] или немного больше кода: [4]
$ perl -ple 'BEGIN{use File::Basename;$/=undef;$sn=basename($ARGV[0]);} $_= "begin 600 $sn\n".(pack "u", $_)."`\nend" if $_' /some/file/to_encode.gz
https://metacpan.org/dist/PerlPowerTools/view/bin/uuencode
https://metacpan.org/dist/PerlPowerTools/view/bin/uudecode