Estranho \ n na string codificada em base64 em Ruby

159

A biblioteca Base64 embutida no Ruby está adicionando alguns '\ n' s. Não consigo descobrir o motivo. Para este exemplo 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"

Os \ n estão na última e na sexta posição do final. O decodificador (Base64.decode64) retorna a string antiga perfeitamente. O estranho é que esses \ n não agregam valor à string codificada. Quando removo as novas linhas da string de saída, o decodificador a decodifica novamente perfeitamente.

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

Além disso, usei uma outra biblioteca JS para produzir a saída codificada em base64 da mesma sequência de entrada, a saída vem sem os \ n's.

Isso é um bug ou algo mais? Alguém já enfrentou esse problema antes?

PARA SUA INFORMAÇÃO,

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
intellidiot
fonte
mesmo problema estranho aqui
Nadav B

Respostas:

223

Edit: Desde que eu escrevi esta resposta Base64.strict_encode64()foi adicionada, o que não adiciona novas linhas.


Os documentos são um pouco confusos, o b64encodemétodo deve adicionar uma nova linha para cada sexagésimo caractere, e o exemplo do encode64método está realmente usando o b64encodemétodo.

Parece que o pack("m")método para a classe Array usado por encode64também adiciona as novas linhas. Eu consideraria um erro de design que isso não seja opcional.

Você mesmo pode remover as novas linhas ou, se estiver usando trilhos, há ActiveSupport :: CoreExtensions :: Base64 :: Encoding com o encode64smétodo

Christoffer Hammarström
fonte
44
Parece que desde que escrevi esta resposta, existe agora strict_encode64()que ostensivamente não adiciona novas linhas.
Christoffer Hammarström
15
Tão burro! Por que você faz isso comigo, Ruby?
21414 Josh
1
Este é um padrão de assinatura, mas como @ ChristofferHammarström menciona, há uma maneira de obter uma verdadeira codificação b64 agora.
Dan
1
Aparentemente, isso existe para manter compatibilidade com versões anteriores de software que não pode lidar com longas filas. stackoverflow.com/a/20065991/5749914
Chimpanzé guerreiro
115

No ruby-1.9.2, você tem o Base64.strict_encode64, que não adiciona \ n (nova linha) no final.

ghtn
fonte
Essa é uma solução muito mais fácil!
Avishai 19/09/2013
Eu verifiquei que Base64.strict_encode64 não está codificado corretamente com três caracteres. como Base64.strict_encode64 ('abc') -> YWJj. o exemplo acima não está codificado corretamente.
CodeMaker 17/09/19
9

Sim, isso é bastante normal. O documento fornece um exemplo demonstrando a divisão de linhas. O base64 faz a mesma coisa em outros idiomas também (por exemplo, Python).

A razão pela qual as novas linhas livres de conteúdo são adicionadas no estágio de codificação é porque o base64 foi originalmente criado como um mecanismo de codificação para o envio de conteúdo binário por email, onde o comprimento da linha é limitado. Sinta-se à vontade para substituí-los, caso não precise deles.

bobince
fonte
1
Isso aconteceu no meu aplicativo Android (biblioteca Base64 do Java). Eu estava totalmente confuso com essa ocorrência estranha. Levei literalmente 1 hora para descobrir o que havia de errado e depois procurei o erro. Este comentário está ajudando a entender os problemas herdados, mesmo após 6 anos.
burglarhobbit
5

Parece que eles precisam ser removidos / ignorados, como:

Base64.encode64(str).gsub(/\n/, '')
meesern
fonte
Esta solução está suja .. mais alguma coisa?
Arnold Roa
1
@yaauie ( via edição sugerida ): edições que fazem uma alteração substancial geralmente não devem ser feitas. Eu recomendo postar isso como uma resposta separada.
Pokechu22
3

Use o strict_encode64método encode64adiciona \ n a cada 60 símbolos

Александр Тихонович
fonte
podemos alterá-lo para adicionar depois de 76 símbolos?
sonic