Strano \ n nella stringa codificata base64 in Ruby


159

La libreria Base64 integrata in Ruby sta aggiungendo alcuni '\ n. Non riesco a scoprire il motivo. Per questo esempio speciale:

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"

I \ n sono all'ultima e alla sesta posizione dalla fine. Il decodificatore (Base64.decode64) restituisce perfettamente la vecchia stringa. La cosa strana è che questi \ n non aggiungono alcun valore alla stringa codificata. Quando rimuovo i newline dalla stringa di output, il decodificatore lo decodifica di nuovo perfettamente.

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

Inoltre, ho usato un'altra libreria JS per produrre l'output codificato in base64 della stessa stringa di input, l'output arriva senza \ n.

È un bug o qualcos'altro? Qualcuno ha affrontato questo problema prima?

Cordiali saluti,

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]

stesso problema strano qui
Nadav B

Risposte:


224

Modifica: da quando ho scritto questa risposta è Base64.strict_encode64()stata aggiunta, che non aggiunge nuove righe.


I documenti sono piuttosto confusi, il b64encodemetodo dovrebbe aggiungere una nuova riga per ogni 60 ° carattere e l'esempio per il encode64metodo sta effettivamente utilizzando il b64encodemetodo.

Sembra che il pack("m")metodo per la classe Array utilizzato da encode64aggiunge anche le nuove righe. Lo considererei un bug di progettazione che questo non è facoltativo.

Puoi rimuovere da solo le newline o, se stai usando le rotaie, c'è ActiveSupport :: CoreExtensions :: Base64 :: Encoding con il encode64smetodo.


44
Sembra che da quando ho scritto questa risposta ora c'è strict_encode64()che apparentemente non aggiunge nuove righe.
Christoffer Hammarström,

15
Così stupido! Perché mi fai questo, Ruby?
Josh M.,

1
Questo è un valore predefinito assinie, ma come menziona @ ChristofferHammarström, ora c'è un modo per ottenere una vera codifica b64.
Dan

1
Apparentemente questo esiste per mantenere la retrocompatibilità con un software che non è in grado di gestire lunghe file. stackoverflow.com/a/20065991/5749914
Warlike Chimpanzee,

115

In ruby-1.9.2 hai Base64.strict_encode64 che non aggiunge quello \ n (newline) alla fine.


Questa è una soluzione molto più semplice!
Avishai,

Ho verificato Base64.strict_encode64 non è codificato correttamente una stringa di tre caratteri. come Base64.strict_encode64 ('abc') -> YWJj. l'esempio sopra non è codificato correttamente.
CodeMaker,

9

Sì, è abbastanza normale. Il documento fornisce un esempio che dimostra la divisione della linea. base64 fa la stessa cosa anche in altre lingue (es. Python).

Il motivo per cui sono state aggiunte nuove righe prive di contenuto nella fase di codifica è perché originariamente base64 è stato concepito come un meccanismo di codifica per l'invio di contenuto binario in e-mail, dove la lunghezza della linea è limitata. Sentiti libero di sostituirli se non ne hai bisogno.


1
Questo è appena successo nella mia app Android (libreria Base64 di Java). Ero totalmente confuso da questo strano avvenimento. Mi ci sono voluti letteralmente 1 ora per capire cosa non andava e poi ho cercato l'errore. Questo commento aiuta a comprendere i problemi legati alla legacy anche dopo 6 anni.
ladro

5

Sembra che debbano essere spogliati / ignorati, come:

Base64.encode64(str).gsub(/\n/, '')

Questa soluzione è sporca ... qualcos'altro?
Arnold Roa,

1
@yaauie ( tramite la modifica suggerita ): le modifiche che apportano una modifica sostanziale generalmente non dovrebbero essere eseguite. Consiglierei di pubblicarlo come risposta separata.
Pokechu22,


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.