Extraño \ n en cadena codificada en base64 en Ruby

159

La biblioteca Base64 incorporada en Ruby está agregando algunos '\ n's. No puedo encontrar la razón. Para este ejemplo especial:

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'base64'
=> true
irb(main):003:0> str =  "1110--ad6ca0b06e1fbeb7e6518a0418a73a6e04a67054"
=> "1110--ad6ca0b06e1fbeb7e6518a0418a73a6e04a67054"
irb(main):004:0> Base64.encode64(str)
=> "MTExMC0tYWQ2Y2EwYjA2ZTFmYmViN2U2NTE4YTA0MThhNzNhNmUwNGE2NzA1\nNA==\n"

Los \ n están en la última y sexta posición desde el final. El decodificador (Base64.decode64) devuelve la cadena antigua perfectamente. Lo extraño es que estos \ n no agregan ningún valor a la cadena codificada. Cuando elimino las líneas nuevas de la cadena de salida, el decodificador la decodifica nuevamente perfectamente.

irb(main):005:0> Base64.decode64(Base64.encode64(str).gsub("\n", '')) == str
=> true

Más de esto, usé otra biblioteca JS para producir la salida codificada en base64 de la misma cadena de entrada, la salida viene sin los \ n.

¿Es esto un error o algo más? ¿Alguien ha enfrentado este problema antes?

FYI

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
Intellidiot
fuente
mismo problema extraño aquí
Nadav B

Respuestas:

224

Editar: desde que escribí esta respuesta Base64.strict_encode64()se agregó, que no agrega nuevas líneas.


Los documentos son algo confusos, b64encodese supone que el método agrega una nueva línea por cada 60 caracteres, y el ejemplo para el encode64método es realmente usar el b64encodemétodo.

Parece que el pack("m")método para la clase Array utilizado por encode64también agrega las nuevas líneas. Consideraría un error de diseño que esto no es opcional.

Puede eliminar las nuevas líneas usted mismo, o si está utilizando rieles, hay ActiveSupport :: CoreExtensions :: Base64 :: Codificación con el encode64smétodo.

Christoffer Hammarström
fuente
44
Parece que desde que escribí esta respuesta ahora hay algo strict_encode64()que aparentemente no agrega nuevas líneas.
Christoffer Hammarström
15
¡Tan tonto! ¿Por qué me haces esto, Ruby?
Josh M.
1
Este es un valor predeterminado, pero como menciona @ ChristofferHammarström, ahora hay una manera de obtener una verdadera codificación b64.
Dan
1
Aparentemente, esto existe para mantener la compatibilidad con software que no puede manejar largas colas. stackoverflow.com/a/20065991/5749914
Warlike Chimpanzee
115

En ruby-1.9.2 tiene Base64.strict_encode64 que no agrega ese \ n (nueva línea) al final.

ghtn
fuente
¡Esa es una solución mucho más fácil!
Avishai
He comprobado que Base64.strict_encode64 no está codificada correctamente en una cadena de tres caracteres. como Base64.strict_encode64 ('abc') -> YWJj. El ejemplo anterior no está codificado correctamente.
CodeMaker
9

Sí, esto es bastante normal. El documento da un ejemplo que demuestra la división de línea. base64 también hace lo mismo en otros idiomas (por ejemplo, Python).

La razón por la que se agregan nuevas líneas sin contenido en la etapa de codificación es porque base64 se diseñó originalmente como un mecanismo de codificación para enviar contenido binario en un correo electrónico, donde la longitud de la línea es limitada. Siéntase libre de reemplazarlos si no los necesita.

bobince
fuente
1
Esto acaba de suceder en mi aplicación de Android (biblioteca Base64 de Java). Estaba totalmente confundido con este extraño suceso. Me llevó literalmente 1 hora descubrir qué está mal y luego busqué el error. Este comentario está ayudando a comprender los problemas heredados incluso después de 6 años.
ladrón
5

Parece que tienen que ser despojados / ignorados, como:

Base64.encode64(str).gsub(/\n/, '')
meesern
fuente
Esta solución está sucia ... ¿hay algo más?
Arnold Roa
1
@yaauie (a través de la edición sugerida ): las ediciones que hacen un cambio sustancial generalmente no deben hacerse. Recomiendo publicar eso como una respuesta separada.
Pokechu22
3

strict_encode64Método de uso encode64agrega \ n cada 60 símbolos

Александр Тихонович
fuente
¿podemos cambiarlo para agregarlo después de 76 símbolos?
sonic