Dziwne \ nw łańcuchu zakodowanym algorytmem base64 w Rubim


159

Wbudowana biblioteka Base64 w Rubim dodaje kilka '\ n'. Nie mogę znaleźć przyczyny. W tym szczególnym przykładzie:

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 są na ostatniej i szóstej pozycji od końca. Dekoder (Base64.decode64) doskonale zwraca stary ciąg. Dziwne jest to, że te \ n nie dodają żadnej wartości do zakodowanego ciągu. Kiedy usuwam znaki nowej linii z ciągu wyjściowego, dekoder dekoduje go ponownie doskonale.

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

Co więcej, użyłem innej biblioteki JS do wytworzenia wyjścia zakodowanego w base64 tego samego ciągu wejściowego, wyjście jest bez \ n.

Czy to błąd czy coś innego? Czy ktoś wcześniej spotkał się z tym problemem?

FYI,

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

ten sam dziwny problem
Nadav B

Odpowiedzi:


223

Edycja: Odkąd napisałem, ta odpowiedź Base64.strict_encode64()została dodana, co nie dodaje nowych linii.


Dokumentacja jest nieco zagmatwana, b64encodemetoda ma dodawać nową linię dla każdego 60-tego znaku, a przykład encode64metody faktycznie używa tej b64encodemetody.

Wygląda na to, że pack("m")metoda klasy Array używana przez encode64również dodaje nowe linie. Uznałbym za błąd projektowy, że nie jest to opcjonalne.

Możesz albo samodzielnie usunąć znaki nowej linii, albo jeśli używasz railsów , możesz skorzystać z encode64smetody ActiveSupport :: CoreExtensions :: Base64 :: Encoding .


44
Wydaje się, że odkąd napisałem tę odpowiedź, jest teraz, strict_encode64()która rzekomo nie dodaje nowych linii.
Christoffer Hammarström

15
Bardzo głupi! Dlaczego mi to robisz, Ruby?
Josh M.

1
Jest to domyślne ustawienie assinie, ale jak wspomina @ ChristofferHammarström, jest sposób na uzyskanie prawdziwego kodowania b64.
Dan

1
Najwyraźniej istnieje po to, aby zachować wsteczną kompatybilność z oprogramowaniem, które nie obsługuje długich linii. stackoverflow.com/a/20065991/5749914
Warlike Chimpanzee

115

W ruby-1.9.2 masz Base64.strict_encode64, który nie dodaje tego \ n (nowej linii) na końcu.


To znacznie łatwiejsze rozwiązanie!
Avishai,

Sprawdziłem, że Base64.strict_encode64 nie jest poprawnie zakodowany trzyznakowy ciąg. jak Base64.strict_encode64 ('abc') -> YWJj. powyższy przykład nie jest poprawnie zakodowany.
CodeMaker

9

Tak, to całkiem normalne. Dokument podaje przykład wykazujące skład podziału. base64 robi to samo również w innych językach (np. Python).

Powodem dodawania nowych linii bez treści na etapie kodowania jest to, że base64 został pierwotnie opracowany jako mechanizm kodowania do wysyłania binarnej zawartości w wiadomości e-mail, gdzie długość linii jest ograniczona. Możesz je wymienić, jeśli ich nie potrzebujesz.


1
To właśnie wydarzyło się w mojej aplikacji na Androida (biblioteka Java Base64). Byłem całkowicie zdezorientowany tym dziwnym zjawiskiem. Zajęło mi dosłownie godzinę, aby dowiedzieć się, co jest nie tak, a następnie szukałem błędu. Ten komentarz pomaga zrozumieć starsze problemy nawet po 6 latach.
włamywacz

5

Wygląda na to, że należy je usunąć / zignorować, na przykład:

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

To rozwiązanie jest brudne… czy gdzie indziej?
Arnold Roa,

1
@yaauie ( poprzez sugerowaną edycję ): zasadniczo nie należy wprowadzać edycji, które powodują istotne zmiany. Polecam opublikowanie tego jako osobnej odpowiedzi.
Pokechu 22


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.