web-dev-qa-db-fra.com

Supprime le "=" suivant lorsque l'encodage en base64

Je remarque que chaque fois que je code une chaîne en base64, un "=" est ajouté à la fin. Puis-je supprimer ce caractère et le décoder de manière fiable ultérieurement en le rajoutant, ou est-ce dangereux? En d'autres termes, le "=" toujours est-il ajouté ou seulement dans certains cas?

Je veux que ma chaîne encodée soit aussi courte que possible, c'est pourquoi je veux savoir si je peux toujours supprimer le caractère "=" et simplement le rajouter avant le décodage.

39
Steve N

Le = est rempli. 

Wikipedia dit

Un caractère de pad supplémentaire est alloué qui peut être utilisé pour forcer la sortie codée en un entier multiple de 4 caractères (ou de manière équivalente lorsque le texte binaire non codé n'est pas un multiple de 3 octets); ces caractères de remplissage doivent alors être mis au rebut lors du décodage mais quand même permettre le calcul de la effective longueur du texte non codé, quand sa la longueur binaire en entrée ne serait pas un multiple de 3 octets (le dernier caractère non-pad est normalement codé de manière à ce que le dernier bloc de 6 bits qu'il représente soit complétée de zéros sur ses bits de poids minimal pad caractères peuvent apparaître à la fin du flux codé .__). 

Si vous contrôlez l’autre extrémité, vous pouvez la supprimer lors du transport, puis la réinsérer (en vérifiant la longueur de la chaîne) avant le décodage.
Notez que les données ne seront pas valides en base64 dans le transport.

56
SLaks

J'ai écrit une partie du décodeur Commons-codec-1.4.jar Base64 d'Apache, et dans cette logique, nous pouvons très bien utiliser des caractères de remplissage. Fin de fichier et fin de flux sont autant d'indicateurs de la fin du message Base64 qu'un nombre quelconque de caractères '='!

La variante URL-Safe que nous avons introduite dans commons-codec-1.4 omet volontairement les caractères de remplissage pour garder les choses plus petites!

http://commons.Apache.org/codec/apidocs/src-html/org/Apache/commons/codec/binary/Base64.html#line.478

J'imagine qu'une réponse plus sûre est "dépend de l'implémentation de votre décodeur", mais logiquement, il n'est pas difficile d'écrire un décodeur qui n'a pas besoin de remplissage.

22
Julius Musseau

En JavaScript, vous pouvez faire quelque chose comme ceci:

// if this is your Base64 encoded string
var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA=='; 

// make URL friendly:
str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');

// reverse to original encoding
if (str.length % 4 != 0){
  str += ('===').slice(0, 4 - (str.length % 4));
}
str = str.replace(/-/g, '+').replace(/_/g, '/');

Voir aussi ce violon: http://jsfiddle.net/7bjaT/66/

20
magikMaker

= est ajouté pour le remplissage. La longueur d'une chaîne base64 doit être multiple de 4, ainsi 1 ou 2 = sont ajoutés selon les besoins.

Lire: Non, vous ne devriez pas l'enlever.

9
Juan Pablo Califano

Sur Android, j'utilise ceci:

Global

String CHARSET_NAME ="UTF-8";

Encoder

String base64 = new String(
            Base64.encode(byteArray, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_CLOSE | Base64.NO_WRAP),
            CHARSET_NAME);
return base64.trim();

Décoder

byte[] bytes = Base64.decode(base64String,
            Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_CLOSE | Base64.NO_WRAP);

est égal à cela sur Java:

Encoder

private static String base64UrlEncode(byte[] input)
{
    Base64 encoder = new Base64(true);
    byte[] encodedBytes = encoder.encode(input);
    return StringUtils.newStringUtf8(encodedBytes).trim();
}

Décoder

private static byte[] base64UrlDecode(String input) {
    byte[] originalValue = StringUtils.getBytesUtf8(input);
    Base64 decoder = new Base64(true);
    return decoder.decode(originalValue);
}

Je n'ai jamais eu de problèmes avec trailing "=" et j'utilise aussi Bouncycastle

3
Code.IT

Si vous utilisez PHP, la fonction suivante rétablira la chaîne supprimée dans son format d'origine avec un remplissage approprié:

<?php

$str = 'base64 encoded string without equal signs stripped';
$str = str_pad($str, strlen($str) + (4 - ((strlen($str) % 4) ?: 4)), '=');

echo $str, "\n";
0
supersan