Warum enthält die base64 eines Strings "\ n"?

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

Die Ausgabe hat eine Rückkehr vor Nw==. Was ist der richtige Weg, um base64 unter Linux zu generieren?

Terminal-Screenshot

Tiina
quelle
5
Sind Sie sicher, dass die Ausgabe einen Zeilenumbruch enthält und nicht nur einen Zeilenumbruch? Dieser Befehl funktionierte gut für mich auf dem Mac. Welches Betriebssystem verwenden Sie?
Ian
47
RFC 2045, in dem Base64 definiert wurde, erfordert eine neue Zeile nach maximal 76 Zeichen. Was lässt Sie denken, dass Ihr Beispiel nicht der richtige Weg ist?
MSalters
24
@MSalters RFC 4648 behebt speziell dieses Problem. Implementierungen DÜRFEN KEINE Zeilenvorschübe zu basiscodierten Daten hinzufügen, es sei denn, die Spezifikation in diesem Dokument weist Basiscodierer explizit an, Zeilenvorschübe nach einer bestimmten Anzahl von Zeichen hinzuzufügen. => Diese Implementierung ist gemäß RFC 4648 nicht korrekt, solange behauptet wird, dass sie eine "einfache" Base64-codierte Ausgabe erzeugt. Interessanter ist, dass die Hilfeseiten zu GNU base64 (in Frage?) Speziell auf RFC 3548 verweisen, in dem auch standardmäßig kein Wrapping angegeben ist und das RFC 4648 veraltet ist.
Bob
4
@Bob: RFCs haben etwas weniger Respekt vor der API-Stabilität. Ein Base64-Tool kann nicht einfach das Ausgabeformat ändern, ohne Skripte zu beschädigen.
MSalters
2
@MSalters Ich kann nicht sicher sein, dass es keine ältere Version gibt, aber GNU base64 wurde 2004 geschrieben und AFAICT behauptete immer, RFC 3548 zu folgen. RFC 3548 enthält dieselbe Klausel "MUSS KEINE Zeilenvorschübe hinzufügen". Somit war auch die ursprüngliche Implementierung "falsch". Zumindest stimmt die Implementierung nicht mit der Dokumentation überein. Wie auch immer, Sie haben gefragt, warum das Beispiel von OP korrekt ist, und auf einen RFC verwiesen. Meine Antwort ist der richtige RFC, der Base64 isoliert definiert. Wenn Ihre Antwort "aus historischen Gründen" ist, ist es so, aber OP ist hier nicht falsch.
Bob

Antworten:

151

Versuchen:

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

Von man base64:

-w, --wrap=COLS
Codierte Zeilen nach dem COLSZeichen umbrechen (Standard 76). Dient 0zum Deaktivieren des Zeilenumbruchs.

Kamil Maciorowski
quelle
17
Oh man, ich habe das immer nur durchgepfeift tr. Gut zu wissen, dass es einen "richtigen Weg" gibt.
Score_Under
Die Erklärung, warum der Standardwert nicht Null ist, ist für mich ein Rätsel.
Dherik
1
@ Dherik Ich denke, es ist höflich gegenüber Textverarbeitungswerkzeugen. base64kodiert beliebige Binärdaten als Text. Tools, die Text erwarten, lesen normalerweise jeweils eine Zeile und können sehr lange Zeilen möglicherweise nicht richtig verarbeiten . Wenn dies -w 0die Standardeinstellung ist, erhalten Sie standardmäßig nur eine Textzeile. eine enorm lange Zeile, wenn die Eingabe groß war. Es ist besser, standardmäßig zu wickeln. Ich denke , 76wurde gewählt , weil es ist etwas weniger als 80der ist eine Art De-facto - Standard für die Terminals .
Kamil Maciorowski
@KamilMaciorowski danke für die Information. Jedes Mal, wenn ich den base64Befehl verwendete, musste ich den Befehl übergeben -w 0(und wenn ich vergaß, können seltsame Dinge passieren ...), so dass dieses Standardverhalten für mich sehr seltsam war.
Dherik
54

Dies ist Kamils ​​Antwort auf Systemen unterlegen, die diese -wOption unterstützen. In base64Fällen, in denen dies nicht verfügbar ist (z. B. Alpine Linux, ein Arch Linux- initramfsHook usw.), können Sie die Ausgabe von base64 manuell verarbeiten:

base64 some_file.txt | tr -d \\n

Dies ist der Brute-Force-Ansatz; Anstatt das Programm zur Zusammenarbeit trzu bewegen , verwende ich, um wahllos jede neue Zeile auf stdout zu entfernen.

Score_Under
quelle