Pourquoi la base64 d'une chaîne contient-elle “\ n”?

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

La sortie a un retour avant Nw==. Quelle est la bonne façon de générer base64 sous Linux?

capture d'écran du terminal

Tiina
la source
5
Etes-vous certain que la sortie contient une nouvelle ligne et qu'il ne s'agit pas uniquement du retour à la ligne? Cette commande a bien fonctionné pour moi sur mac. Quel système d'exploitation utilisez-vous?
Ian
47
La RFC 2045, qui définit Base64, NÉCESSITE une nouvelle ligne après 76 caractères (max). Qu'est-ce qui vous fait penser que votre exemple n'est pas la bonne?
MSalters
24
@MSalters RFC 4648 traite spécifiquement de ce problème. Les implémentations NE DOIVENT PAS ajouter de sauts de ligne aux données codées en base, à moins que la spécification faisant référence à ce document n'indique explicitement aux codeurs de base d'ajouter des sauts de ligne après un nombre spécifique de caractères. => cette implémentation est incorrecte selon la norme RFC 4648, dans la mesure où elle prétend produire une sortie "ordinaire" codée en base64. Plus intéressant encore, les pages de manuel GNU base64 (en question?) Font spécifiquement référence à la RFC 3548, qui spécifie également qu’il ne faut pas de wrapping par défaut, et que la RFC 4648 est obsolète.
Bob
4
@Bob: les RFC respectent un peu moins la stabilité des API; un outil base64 ne peut pas simplement changer son format de sortie sans casser des scripts.
MSalters
2
@MSalters Je ne peux pas être sûr qu'une version plus ancienne n'existe pas, mais GNU base64 a été écrit en 2004 et AFAICT a toujours prétendu suivre RFC 3548. La RFC 3548 contient la même clause "NE DOIT PAS ajouter de saut de ligne". Donc, même la mise en œuvre initiale était "fausse". À tout le moins, sa mise en œuvre ne correspond pas à sa documentation. Quoi qu'il en soit, vous avez demandé pourquoi l'exemple d'OP est correct et vous avez référencé une RFC; Ma réponse est la RFC correcte qui définit réellement base64 de manière isolée. Si votre réponse est "pour des raisons historiques", ainsi soit-il, mais OP n'a pas tort ici.
Bob

Réponses:

151

Essayer:

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

De man base64:

-w, --wrap=COLS
Retournez les lignes codées après le COLScaractère (par défaut 76). Utilisez 0pour désactiver le retour à la ligne.

Kamil Maciorowski
la source
17
Oh mec, j'ai toujours passé ça tr. C'est bon de savoir qu'il y a un "bon chemin".
Score_Under
L'explication sur le fait que la valeur par défaut n'est pas zéro est un mystère pour moi.
Dherik
1
@ Dherik Je suppose que c'est de la courtoisie envers les outils de traitement de texte. base64code les données binaires arbitraires sous forme de texte. Les outils qui attendent du texte lisent généralement une ligne à la fois et peuvent ne pas traiter correctement les longues lignes . Si -w 0était la valeur par défaut, vous obtiendriez par défaut une seule ligne de texte; une ligne extrêmement longue si l'entrée était grande. Il vaut mieux envelopper par défaut. Je pense avoir 76été choisi parce que c’est un peu moins que 80ce qui est une sorte de standard de facto pour les terminaux .
Kamil Maciorowski
@ Kamil Maciorowski merci pour l'information. Chaque fois que j'utilisais la base64commande, je devais passer le mot -w 0(et quand j'oubliais, des choses étranges peuvent se produire ...), donc ce comportement par défaut était très étrange pour moi.
Dherik
54

Ceci est inférieur à la réponse de Kamil sur les systèmes qui prennent en charge l' -woption base64, mais dans les cas où cela n'est pas disponible (par exemple, Alpine Linux, un initramfshook Arch Linux , etc.), vous pouvez traiter manuellement la sortie de base64:

base64 some_file.txt | tr -d \\n

C'est l'approche de la force brute; au lieu de faire coopérer le programme, j’utilise trpour effacer sans distinction toutes les nouvelles lignes sur stdout.

Score_Under
la source