Почему base64 строки содержит «\ n»?

84
$ echo -n "apfjxkic-omyuobwd339805ak:60a06cd2ddfad610b9490d359d605407" | base64
YXBmanhraWMtb215dW9id2QzMzk4MDVhazo2MGEwNmNkMmRkZmFkNjEwYjk0OTBkMzU5ZDYwNTQw
Nw==

Выход имеет возврат раньше Nw==. Как правильно генерировать base64 в Linux?

снимок экрана терминала

Тийна
источник
5
Вы уверены, что вывод содержит новую строку, и это не просто перенос окна? Эта команда отлично работала для меня на Mac. Какую ОС вы используете?
Ян
47
RFC 2045, который определил Base64, ТРЕБУЕТ перевод строки после 76 символов (макс.). Что заставляет вас думать, что ваш пример не правильный путь?
MSalters
24
@MSalters RFC 4648 специально решает эту проблему. Реализации НЕ ДОЛЖНЫ добавлять переводы строки к базовым кодированным данным, если только спецификация, ссылающаяся на этот документ, явно не предписывает базовым кодировщикам добавлять переводы строк после определенного количества символов. => эта реализация неверна в соответствии с RFC 4648, если она заявляет, что производит «простой» base64-кодированный вывод. Более интересно то, что руководства GNU base64 (в вопросе?) Конкретно ссылаются на RFC 3548, который также не определяет перенос по умолчанию и который RFC 4648 устарел.
Боб
4
@Bob: RFC немного меньше уважают стабильность API; инструмент base64 не может просто изменить свой формат вывода, не нарушая сценарии.
MSalters
2
@MSalters Я не могу быть уверен, что более старой версии не существует, но GNU base64 был написан в 2004 году, и AFAICT всегда утверждал, что следует RFC 3548. RFC 3548 содержит то же самое предложение «НЕ ДОЛЖНО добавлять переводы строк». Так что даже оригинальная реализация была «неправильной». По крайней мере, его реализация не соответствует документации. В любом случае, вы спросили, почему пример OP верен и ссылаются на RFC; Мой ответ - правильный RFC, который фактически определяет base64 изолированно. Если ваш ответ «по историческим причинам», пусть будет так, но ОП здесь не так.
Боб

Ответы:

151

Пытаться:

echo -n "apfjxkic-omyuobwd339805ak:60a06cd2ddfad610b9490d359d605407" | base64 -w 0

От man base64:

-w, --wrap=COLS
Обтекание закодированных строк после COLSсимвола (по умолчанию 76). Используйте 0для отключения переноса строк.

Камиль Мачоровски
источник
17
О, чувак, я всегда просто пропускал это tr. Приятно знать, что есть "правильный путь".
Score_Under
Объяснение того, почему значение по умолчанию не равно нулю, для меня загадка.
Дерик
1
@ Дерик Я думаю, это вежливость по отношению к инструментам обработки текста. base64кодирует произвольные двоичные данные в виде текста. Инструменты, которые ожидают текст, обычно читают по одной строке за раз и могут не справляться с очень длинными строками . Если бы это -w 0было по умолчанию, вы бы получили по умолчанию только одну строку текста; очень длинная строка, если вход был большим. По умолчанию лучше обернуть. Я думаю, что 76был выбран, потому что он немного меньше того, 80который является своего рода стандартом де-факто для терминалов .
Камиль Мачоровский
@KamilMaciorowski спасибо за информацию. Каждый раз, когда я использовал base64команду, мне нужно было передать -w 0(и когда я забыл, странные вещи могут случиться ...), так что это поведение по умолчанию было очень странным для меня.
Дерик
54

Это уступает ответу Камиля на системах, которые поддерживают эту -wопцию base64, но для случаев, когда она недоступна (например, Alpine Linux, initramfsхук Arch Linux и т. Д.), Вы можете вручную обработать вывод base64:

base64 some_file.txt | tr -d \\n

Это подход грубой силы; вместо того, чтобы заставить программу сотрудничать, я использую, trчтобы без разбора раздеть каждую новую строку на stdout.

Score_Under
источник