¿Por qué la base64 de una cadena contiene "\ n"?

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

La salida tiene un retorno antes Nw==. ¿Cuál es la forma correcta de generar base64 en Linux?

captura de pantalla del terminal

Tiina
fuente
55
¿Está seguro de que la salida contiene una nueva línea, y no es solo el ajuste de su ventana? Ese comando funcionó bien para mí en Mac. ¿Qué sistema operativo estás usando?
Ian
47
RFC 2045, que definió Base64, REQUIERE una nueva línea después de 76 caracteres (máx.). ¿Qué te hace pensar que tu ejemplo no es el correcto?
MSalters
24
@MSalters RFC 4648 aborda específicamente ese problema. Las implementaciones NO DEBEN agregar saltos de línea a los datos codificados en base a menos que la especificación que hace referencia a este documento indique explícitamente que los codificadores base agreguen saltos de línea después de un número específico de caracteres. => esta implementación es incorrecta de acuerdo con RFC 4648, siempre y cuando pretenda producir una salida codificada en base64 'sin formato'. Más interesante aún, las páginas de manual de GNU base64 (¿en cuestión?) Se refieren específicamente a RFC 3548, que también especifica que no hay ajuste por defecto, y que RFC 4648 está obsoleto.
Bob
44
@Bob: los RFC tienen un poco menos de respeto por la estabilidad de la API; una herramienta base64 no puede simplemente cambiar su formato de salida sin romper los scripts.
MSalters
2
@MSalters No puedo estar seguro de que no exista una versión anterior, pero GNU base64 se escribió en 2004 y AFAICT siempre afirmó seguir RFC 3548. RFC 3548 contiene la misma cláusula "NO DEBE agregar saltos de línea". Entonces, incluso la implementación original fue "incorrecta". Como mínimo, su implementación no coincide con su documentación. De todos modos, usted preguntó por qué el ejemplo de OP es correcto y hizo referencia a un RFC; mi respuesta es el RFC correcto que realmente define base64 de forma aislada. Si su respuesta es "por razones históricas", que así sea, pero OP no está mal aquí.
Bob

Respuestas:

151

Tratar:

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

De man base64:

-w, --wrap=COLS
Ajustar líneas codificadas después del COLScarácter (predeterminado 76). Use 0para deshabilitar el ajuste de línea.

Kamil Maciorowski
fuente
17
Oh hombre, siempre lo decía tr. Es bueno saber que hay una "forma correcta".
Score_Under
La explicación sobre por qué el valor predeterminado no es cero es un misterio para mí.
Dherik
1
@Dherik Supongo que es cortesía hacia las herramientas de procesamiento de texto. base64codifica datos binarios arbitrarios como texto. Las herramientas que esperan texto generalmente leen una línea a la vez y es posible que no manejen bien las líneas muy largas . Si -w 0fuera el predeterminado, obtendría por defecto solo una línea de texto; una línea enormemente larga si la entrada era grande. Es mejor envolver por defecto. Creo que 76fue elegido porque es poco menos de lo 80que es una especie de estándar de facto para terminales .
Kamil Maciorowski
@KamilMaciorowski gracias por la información. Cada vez que usaba el base64comando necesitaba pasar el -w 0(y cuando lo olvidé, pueden suceder cosas extrañas ...), por lo que este comportamiento predeterminado fue muy extraño para mí.
Dherik
54

Esto es inferior a la respuesta de Kamil en sistemas que admiten la -wopción base64, pero para los casos en que no está disponible (por ejemplo, Alpine Linux, un initramfsgancho Arch Linux , etc.), puede procesar manualmente la salida de base64:

base64 some_file.txt | tr -d \\n

Este es el enfoque de fuerza bruta; en lugar de lograr que el programa coopere, estoy usando trpara eliminar indiscriminadamente cada línea nueva en stdout.

Score_Under
fuente