Por que a base64 de uma string contém "\ n"?

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

A saída tem um retorno antes Nw==. Qual é a maneira correta de gerar base64 no Linux?

captura de tela do terminal

Tiina
fonte
5
Você tem certeza de que a saída contém uma nova linha e não é apenas a quebra de sua janela? Esse comando funcionou bem para mim no mac. Qual sistema operacional você está usando?
Ian
47
O RFC 2045, que definiu Base64, EXIGE uma nova linha após 76 caracteres (no máximo). O que faz você pensar que seu exemplo não é o caminho correto?
MSalters
24
O @MSalters RFC 4648 aborda especificamente esse problema. As implementações NÃO DEVEM adicionar feeds de linha aos dados codificados em base, a menos que a especificação referente a este documento direcione explicitamente os codificadores de base para adicionar feeds de linha após um número específico de caracteres. => esta implementação está incorreta de acordo com a RFC 4648, desde que pretenda produzir uma saída codificada em base64 'simples'. Mais interessante, as páginas de manual do GNU base64 (em questão?) Referem-se especificamente ao RFC 3548, que também especifica nenhum empacotamento por padrão e que o RFC 4648 obsoleta.
Bob
4
@ Bob: as RFCs têm um pouco menos de respeito pela estabilidade da API; uma ferramenta base64 não pode simplesmente mudar seu formato de saída sem interromper os scripts.
MSalters
2
@MSalters Não posso ter certeza de que não existe uma versão mais antiga, mas o GNU base64 foi escrito em 2004 e o AFAICT sempre afirmou seguir a RFC 3548. A RFC 3548 contém a mesma cláusula "NÃO DEVE adicionar feeds de linha". Portanto, mesmo a implementação original estava "errada". No mínimo, sua implementação não corresponde à sua documentação. Enfim, você perguntou por que o exemplo do OP está correto e referenciou uma RFC; minha resposta é a RFC correta que realmente define a base64 isoladamente. Se sua resposta for "por razões históricas", que seja, mas o OP não está errado aqui.
Bob

Respostas:

151

Experimentar:

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

De man base64:

-w, --wrap=COLS
Quebrar linhas codificadas após o COLScaractere (padrão 76). Use 0para desativar a quebra de linha.

Kamil Maciorowski
fonte
17
Oh cara, eu sempre acabei de passar isso tr. É bom saber que existe uma "maneira adequada".
Score_Und
A explicação sobre por que o valor padrão não é zero é um mistério para mim.
Dherik 25/07
11
@ Dherik Eu acho que é uma cortesia para as ferramentas de processamento de texto. base64codifica dados binários arbitrários como texto. As ferramentas que esperam texto geralmente leem uma linha por vez e podem não lidar bem com linhas muito longas . Se -w 0fosse o padrão, você obteria por padrão apenas uma linha de texto; uma linha enormemente longa se a entrada for grande. É melhor agrupar por padrão. Eu acho que 76foi escolhido porque é um pouco menos do 80que é uma espécie de padrão de fato para terminais .
Kamil Maciorowski 25/07
@KamilMaciorowski obrigado pela informação. Toda vez que eu usava o base64comando eu precisava passar o -w 0(e quando eu esqueci, coisas estranhas podem acontecer ...), então esse comportamento padrão era muito estranho para mim.
Dherik 25/07
54

Isso é inferior à resposta de Kamil em sistemas que suportam a -wopção base64, mas nos casos em que isso não está disponível (por exemplo, Alpine Linux, um initramfsgancho do Arch Linux , etc.), você pode processar manualmente a saída do base64:

base64 some_file.txt | tr -d \\n

Essa é a abordagem da força bruta; em vez de fazer o programa cooperar, estou usando trpara retirar indiscriminadamente todas as novas linhas do stdout.

Score_Under
fonte