Strange \ n dalam string yang disandikan base64 di Ruby

159

Pustaka Base64 inbuilt di Ruby menambahkan beberapa '\ n's. Saya tidak dapat menemukan alasannya. Untuk contoh khusus ini:

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"

\ N berada pada posisi terakhir dan keenam dari ujung. Decoder (Base64.decode64) mengembalikan string yang lama dengan sempurna. Anehnya, ini tidak menambah nilai ke string yang dikodekan. Ketika saya menghapus baris baru dari string output, decoder menerjemahkannya lagi dengan sempurna.

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

Lebih dari ini, saya menggunakan pustaka JS lain untuk menghasilkan output disandikan base64 dari string input yang sama, output datang tanpa \ n's.

Apakah ini bug atau yang lainnya? Adakah yang pernah mengalami masalah ini sebelumnya?

FYI,

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
intellidiot
sumber
masalah aneh yang sama di sini
Nadav B

Jawaban:

224

Sunting: Karena saya menulis jawaban Base64.strict_encode64()ini ditambahkan, yang tidak menambahkan baris baru.


Dokumen agak membingungkan, b64encodemetode ini seharusnya menambahkan baris baru untuk setiap karakter ke-60, dan contoh untuk encode64metode ini sebenarnya menggunakan b64encodemetode tersebut.

Tampaknya pack("m")metode untuk kelas Array yang digunakan oleh encode64juga menambahkan baris baru. Saya akan menganggapnya sebagai bug desain bahwa ini bukan opsional.

Anda bisa menghapus baris baru sendiri, atau jika Anda menggunakan rel, ada ActiveSupport :: CoreExtensions :: Base64 :: Pengkodean dengan encode64smetode ini.

Christoffer Hammarström
sumber
44
Tampaknya sejak saya menulis jawaban ini sekarang ada strict_encode64()yang seolah-olah tidak menambahkan baris baru.
Christoffer Hammarström
15
Bodoh sekali! Kenapa kau melakukan ini padaku, Ruby?
Josh M.
1
Ini adalah default assinie, tetapi seperti @ ChristofferHammarström menyebutkan, ada cara untuk mendapatkan enkode b64 yang benar sekarang.
Dan
1
Rupanya ini ada untuk mempertahankan backat compat dengan perangkat lunak yang tidak dapat menangani garis panjang. stackoverflow.com/a/20065991/5749914
Warlike Chimpanzee
115

Di ruby-1.9.2 Anda memiliki Base64.strict_encode64 yang tidak menambahkan \ n (baris baru) di akhir.

ghtn
sumber
Itu solusi yang jauh lebih mudah!
Avishai
Saya telah memeriksa Base64.strict_encode64 tidak dikodekan dengan benar tiga karakter string. seperti Base64.strict_encode64 ('abc') -> YWJj. contoh di atas tidak dikodekan dengan benar.
Pembuat kode
9

Ya, ini sangat normal. The doc memberi contoh menunjukkan garis-membelah. base64 juga melakukan hal yang sama dalam bahasa lain (mis. Python).

Alasan baris baru bebas konten ditambahkan pada tahap penyandian adalah karena base64 pada awalnya dirancang sebagai mekanisme penyandian untuk mengirim konten biner dalam email, di mana panjang garis dibatasi. Jangan ragu untuk menggantinya jika Anda tidak membutuhkannya.

bobince
sumber
1
Ini baru saja terjadi di Aplikasi Android saya (perpustakaan Base64 Java). Saya benar-benar bingung dengan kejadian aneh ini. Butuh waktu 1 jam untuk mencari tahu apa yang salah dan kemudian mencari kesalahan. Komentar ini membantu memahami masalah warisan bahkan setelah 6 tahun.
burglarhobbit
5

Sepertinya mereka harus ditelanjangi / diabaikan, seperti:

Base64.encode64(str).gsub(/\n/, '')
meesern
sumber
Solusi ini kotor .. ada lagi?
Arnold Roa
1
@yaauie ( via sunting yang disarankan ): Suntingan yang melakukan perubahan besar umumnya tidak boleh dilakukan. Saya akan merekomendasikan memposting itu sebagai jawaban terpisah.
Pokechu22
3

Gunakan strict_encode64metode. encode64menambahkan \ n setiap 60 simbol

Александр Тихонович
sumber
dapatkah kita mengubahnya untuk menambahkan setelah 76 simbol?
sonic