Странно \ n в кодированной строке base64 в Ruby

159

Встроенная библиотека Base64 в Ruby добавляет некоторые символы \ n. Я не могу выяснить причину. Для этого особого примера:

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 в последней и 6-й позиции от конца. Декодер (Base64.decode64) отлично возвращает старую строку. Странно то, что эти \ n не добавляют никакого значения к закодированной строке. Когда я удаляю символы новой строки из выходной строки, декодер снова прекрасно их декодирует.

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

Более того, я использовал другую библиотеку JS для получения закодированных в base64 выходных данных той же входной строки, выходной файл не имеет \ n.

Это ошибка или что-то еще? Кто-нибудь сталкивался с этой проблемой раньше?

FYI,

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
intellidiot
источник
та же самая странная проблема здесь
Nadav B

Ответы:

224

Изменить: так как я написал этот ответ Base64.strict_encode64()был добавлен, который не добавляет новые строки.


Документы несколько сбивают с толку, b64encodeпредполагается , что метод добавляет новую строку для каждого 60-го символа, и пример для encode64метода на самом деле использует b64encodeметод.

Похоже, что pack("m")метод для класса Array, который используется, encode64также добавляет символы новой строки. Я бы посчитал ошибкой дизайна, что это не обязательно.

Вы можете либо удалить символы новой строки самостоятельно, либо, если вы используете rails, есть ActiveSupport :: CoreExtensions :: Base64 :: Кодировка с помощью encode64sметода.

Кристоффер Хаммарстрём
источник
44
Похоже, что с тех пор, как я написал этот ответ, теперь strict_encode64()якобы не добавляются новые строки.
Кристофер Хаммарстрём,
15
Настолько глуп! Зачем ты это делаешь со мной, Руби?
Джош М.
1
Это стандартное значение по умолчанию, но, как упоминает @ ChristofferHammarström, есть способ получить настоящую кодировку b64.
Дан
1
По-видимому, это существует для обеспечения обратной совместимости с программным обеспечением, которое не может обрабатывать длинные строки. stackoverflow.com/a/20065991/5749914
Воинственный шимпанзе
115

В ruby-1.9.2 у вас есть Base64.strict_encode64, который не добавляет этот \ n (перевод строки) в конце.

ghtn
источник
Это гораздо более простое решение!
Авишай
Я проверил Base64.strict_encode64 неправильно закодированную трехсимвольную строку. как Base64.strict_encode64 ('abc') -> YWJj. приведенный выше пример закодирован неправильно.
CodeMaker
9

Да, это вполне нормально. В документе приведен пример, демонстрирующий разделение строк. base64 делает то же самое и в других языках (например, Python).

Причина того, что новые строки без содержания добавляются на этапе кодирования, заключается в том, что base64 изначально была разработана как механизм кодирования для отправки двоичного содержимого в электронную почту, где длина строки ограничена. Не стесняйтесь заменить их, если они вам не нужны.

bobince
источник
1
Это только что произошло в моем приложении для Android (Java-библиотека Base64). Я был полностью смущен этим странным происшествием. Мне потребовался буквально 1 час, чтобы понять, что не так, а затем искал ошибку. Этот комментарий помогает понять проблемы наследства даже после 6 лет.
burglarhobbit
5

Кажется, они должны быть раздеты / проигнорированы, как:

Base64.encode64(str).gsub(/\n/, '')
meesern
источник
Это решение грязное .. что-нибудь еще?
Арнольд Роа
1
@yaauie ( через предлагаемое редактирование ): Редактирование, которое вносит существенные изменения, как правило, не должно быть сделано. Я бы рекомендовал опубликовать это как отдельный ответ.
Pokechu22
3

Используйте strict_encode64метод. encode64добавляет \ n каждые 60 символов

Александр Тихонович
источник
мы можем изменить это, чтобы добавить после 76 символов?
Соник