Etrange \ n dans une chaîne encodée en base64 en Ruby

159

La bibliothèque Base64 intégrée dans Ruby ajoute quelques '\ n's. Je suis incapable de trouver la raison. Pour cet exemple spécial:

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"

Les \ n sont à la dernière et à la 6ème position à partir de la fin. Le décodeur (Base64.decode64) renvoie parfaitement l'ancienne chaîne. Ce qui est étrange, c'est que ces \ n n'ajoutent aucune valeur à la chaîne codée. Lorsque je supprime les nouvelles lignes de la chaîne de sortie, le décodeur la décode à nouveau parfaitement.

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

De plus, j'ai utilisé une autre bibliothèque JS pour produire la sortie encodée en base64 de la même chaîne d'entrée, la sortie est livrée sans les \ n.

Est-ce un bug ou autre chose? Quelqu'un a-t-il déjà été confronté à ce problème?

FYI,

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
intellidiot
la source
même problème étrange ici
Nadav B

Réponses:

224

Edit: Depuis que j'ai écrit, cette réponse a Base64.strict_encode64()été ajoutée, ce qui n'ajoute pas de nouvelles lignes.


Les documents sont quelque peu déroutants, la b64encodeméthode est censée ajouter une nouvelle ligne pour chaque 60e caractère, et l'exemple de la encode64méthode utilise en fait la b64encodeméthode.

Il semble que la pack("m")méthode de la classe Array utilisée par encode64ajoute également les nouvelles lignes. Je considérerais comme un bug de conception que ce n'est pas facultatif.

Vous pouvez soit supprimer les nouvelles lignes vous-même, soit si vous utilisez des rails, il y a ActiveSupport :: CoreExtensions :: Base64 :: Encoding avec la encode64sméthode.

Christoffer Hammarström
la source
44
Il semble que depuis que j'ai écrit cette réponse, il y a maintenant strict_encode64()qui n'ajoute apparemment pas de nouvelles lignes.
Christoffer Hammarström
15
Si bête! Pourquoi tu me fais ça, Ruby?
Josh M.
1
C'est une valeur par défaut assinie, mais comme le mentionne @ ChristofferHammarström, il existe un moyen d'obtenir un véritable encodage b64 maintenant.
Dan
1
Apparemment, cela existe pour maintenir la compatibilité avec les logiciels qui ne peuvent pas gérer de longues lignes. stackoverflow.com/a/20065991/5749914
Warlike Chimpanzee
115

Dans ruby-1.9.2, vous avez Base64.strict_encode64 qui n'ajoute pas cela \ n (nouvelle ligne) à la fin.

ghtn
la source
C'est une solution bien plus simple!
Avishai
J'ai vérifié que Base64.strict_encode64 n'est pas correctement encodé une chaîne de trois caractères. comme Base64.strict_encode64 ('abc') -> YWJj. l'exemple ci-dessus n'est pas codé correctement.
CodeMaker
9

Ouais, c'est tout à fait normal. Le document donne un exemple illustrant le fractionnement de ligne. base64 fait la même chose dans d'autres langages (par exemple Python).

La raison pour laquelle des nouvelles lignes sans contenu sont ajoutées au stade de l'encodage est que la base64 a été initialement conçue comme un mécanisme de codage pour l'envoi de contenu binaire par courrier électronique, où la longueur de ligne est limitée. N'hésitez pas à les remplacer si vous n'en avez pas besoin.

bobince
la source
1
Cela vient de se passer dans mon application Android (bibliothèque Java Base64). J'étais totalement confus avec cet étrange événement. Il m'a fallu littéralement 1 heure pour comprendre ce qui ne va pas, puis j'ai recherché l'erreur. Ce commentaire aide à comprendre les problèmes hérités même après 6 ans.
cambrioleur
5

Il semble qu'ils doivent être supprimés / ignorés, comme:

Base64.encode64(str).gsub(/\n/, '')
meesern
la source
Cette solution est sale ... autre chose?
Arnold Roa
1
@yaauie ( via une modification suggérée ): Les modifications qui apportent un changement substantiel ne doivent généralement pas être effectuées. Je recommanderais de publier cela comme une réponse distincte.
Pokechu22
3

Utilisez la strict_encode64méthode. encode64ajoute \ n tous les 60 symboles

Александр Тихонович
la source
pouvons-nous le changer pour ajouter après 76 symboles?
sonic le