Pourquoi une chaîne encodée en base64 a-t-elle un signe = à la fin

322

Je sais ce qu'est l' base64encodage et comment calculer l' base64encodage en C #, mais j'ai vu plusieurs fois que lorsque je convertis une chaîne en base64, il y en a un =à la fin.

Quelques questions se sont posées:

  1. Une base64chaîne se termine- t-elle toujours par =?
  2. Pourquoi un =get est-il ajouté à la fin?
santosh singh
la source
9
Cela n'a absolument rien à voir avec C #.
BoltClock
19
En fait, il est lié à c #, tous les langages n'incluront pas le =, par exemple de nombreuses bibliothèques Perl omettent le =, donc connaître l'environnement que l'utilisateur utilise est en fait pertinent.
Jacob
Il semble que cela en fasse une méthode d'obscurcissement moins efficace dans certains cas car elle est tout à fait détectable.
dgo
6
@ user1167442 Base64 n'est pas destiné à l'obscurcissement. C'est pour transporter des données binaires (ou des chaînes avec unicode et d'autres caractères spéciaux) sous forme de chaîne.
NH.

Réponses:

270

Il sert de rembourrage .

Une réponse plus complète est qu'une chaîne encodée en base64 ne se termine pas toujours par un =, elle ne se terminera par un ou deux que =si elles doivent remplir la chaîne à la bonne longueur.

Andrew Hare
la source
3
"Un cas dans lequel des caractères de remplissage sont requis est la concaténation de plusieurs fichiers encodés en Base64."
André Puel
1
@ AndréPuel: resynchroniser un single =suffirait. Si vous souhaitez retrouver les limites, un terminateur doit toujours être présent (et un seul caractère est toujours nécessaire). Tout le concept de rembourrage de Base64 n'est qu'un brainfart ...
6502
5
Ce lien n'est cependant pas pertinent pour base64.
NH.
1
Je souhaite juste qu'un lien pertinent et fiable soit publié pour expliquer base64efficacement le remplissage avec des illustrations et des exemples. Le lien actuel vers wikipedia n'est absolument pas pertinent comme @NH. mentionné.
Fr0zenFyr
1
@ Fr0zenFyr Si vous voulez un lien, en.wikipedia.org/wiki/Base64#Output_padding est plutôt bon. Mais la réponse de Badr est vraiment meilleure (elle n'a tout simplement pas encore rattrapé les votes).
NH.
313

1-Non

2- En guise de réponse courte: le 65ème caractère (signe "=") n'est utilisé qu'en complément dans le processus final de codage d'un message.

Vous n'aurez pas de signe «=» si votre chaîne a un multiple de 3 caractères, car l' Base64encodage prend chacun trois octets (8 bits) et les représente comme quatre caractères imprimables dans la norme ASCII.

Détails :

(a) Si vous voulez encoder

ABCDEFG <=> [ ABC] [ DEF] [G

Base64traitera (produisant 4 caractères) le premier bloc et le second (car ils sont complets) mais pour le troisième il ajoutera un double ==dans la sortie afin de compléter les 4 caractères nécessaires. Ainsi, le résultat sera QUJD REVG Rw == (sans espace)

(b) Si vous voulez encoder ...

ABCDEFGH <=> [ ABC] [ DEF] [GH

De même, il n'en ajoutera qu'un seul =à la fin de la sortie pour obtenir 4 caractères le résultat sera QUJD REVG R0g = (sans espace)

Badr Bellaj
la source
26
C'est plus complet et clair que les autres réponses et même Wikipedia et devrait mériter plus de votes que la réponse acceptée qui ne fait que pointer vers le lien wikipedia. Bravo à vous! A voté!
ANewGuyInTown
2
@ANewGuyInTown le lien wikipedia dans la solution acceptée est incorrect, il n'a rien à voir avec le remplissage sur base64. La page correcte a été liée par Legolas dans sa réponse ci
Fr0zenFyr
Une autre bonne réponse (à
mon humble avis
66

De Wikipédia :

La séquence finale '==' indique que le dernier groupe ne contenait qu'un seul octet, et '=' indique qu'il contenait deux octets.

Il s'agit donc d'une sorte de rembourrage.

Legolas
la source
16
  1. Non.
  2. Remplir la chaîne encodée en Base64 sur un multiple de 4 caractères afin qu'elle puisse être décodée correctement.
Ian Kemp
la source
3
J'ai supprimé le =à la fin et l' ai testé pour 1 million de cordes. Le décodage correspondait toujours.
vivek_23
15

Il est défini dans la RFC 2045 comme un caractère de remplissage spécial si moins de 24 bits sont disponibles à la fin des données codées.

iandotkelly
la source
11

Le signe égal (=) est utilisé comme remplissage dans certaines formes d'encodage base64. L' article Wikipedia sur base64 contient tous les détails.

Sam Holloway
la source
2
Pourriez-vous expliquer la logique de la raison pour laquelle "==" est 1 octet et "=" est 2 octets? Je ne peux tout simplement pas le comprendre. Comment se fait-il que l'entrée: "tout plaisir charnel". pourrait obtenir le résultat "YW55IGNhcm5hbCBwbGVhc3VyZS4 =", tandis que "tout plaisir charnel" pourrait obtenir le résultat "YW55IGNhcm5hbCBwbGVhc3VyZQ =="?
null
14
Ce n'est pas le cas où '==' est 1 octet et '=' est 2 octets. C'est le cas que vous devez toujours avoir un multiple de 4 octets dans toute votre chaîne. Donc, vous remplissez avec des signes «=» jusqu'à ce que vous obteniez cela. La première chaîne a un caractère de plus que la deuxième chaîne, donc un moins de «=» de remplissage est requis.
Sam Holloway
2
Cette réponse est-elle censée être un commentaire?
Fr0zenFyr
9

C'est du rembourrage. Depuis http://en.wikipedia.org/wiki/Base64 :

En théorie, le caractère de remplissage n'est pas nécessaire pour le décodage, car le nombre d'octets manquants peut être calculé à partir du nombre de chiffres Base64. Dans certaines implémentations, le caractère de remplissage est obligatoire, tandis que pour d'autres, il n'est pas utilisé. Un cas dans lequel des caractères de remplissage sont requis est la concaténation de plusieurs fichiers encodés en Base64.

Thomas Leonard
la source
1
La partie «Un cas dans lequel des caractères de remplissage sont requis est la concaténation de plusieurs fichiers encodés en Base64». est faux. Par exemple, lors de la concaténation de deux fichiers base64 où les octets source de chaque fichier ont une longueur de 3 octets, les chaînes base64 auront 4 caractères et n'auront pas d'octets de remplissage. Lorsque vous concaténerez ces deux chaînes base64, il n'y aura aucun moyen de dire où l'on démarre et on s'arrête en fonction uniquement de la chaîne concaténée. Donc, compter sur le rembourrage base64 pour aider à cela ne fonctionnera pas. Ce problème existera pour tout fichier avec des longueurs d'octet divisibles par 3.
Ron C
1
Je suppose que cela signifie le cas où le résultat final devrait être la concaténation des entrées. par exemple decode(encode(A)+encode(B))=A+Bfonctionne avec un rembourrage mais pas sans.
Thomas Leonard
peut-être, mais une telle utilisation limitée ne permet pas de se fier aux caractères de remplissage pour le cas général de la séparation des chaînes codées lorsque les chaînes codées sont concaténées ensemble. Je ne le mentionne que pour aider les développeurs qui pensent peut-être pouvoir l'utiliser de cette façon.
Ron C
1
Je pense que votre objection ne fait que souligner la différence entre les concepts de rembourrage et de délimitation. On ne s'attend généralement pas à ce que les résultats de la concaténation contiennent suffisamment d'informations pour la rendre réversible. Vous ne saurez pas si "c3dpenpsZXJz" était à l'origine "c3dpenps" + "ZXJz" ou "c3dp" + "enpsZXJz". Mais vous ne savez pas non plus si "swizzlers" était à l'origine "swi" + "zzlers" ou "swizzl" + "ers".
GargantuChet
1
Copier mon commentaire à partir d'une réponse de remplissage Base64 connexe :> La concaténation Base64 [avec le remplissage '='] permet aux encodeurs de traiter de gros morceaux en parallèle sans avoir à aligner les tailles de morceaux sur un multiple de trois. De même, en tant que détail d'implémentation, il peut y avoir un encodeur qui doit vider un tampon de données interne d'une taille qui n'est pas un multiple de trois.
Andre D
7

http://www.hcidata.info/base64.htm

Encodage de "Mary had" en Base 64

Dans cet exemple, nous utilisons une simple chaîne de texte ("Mary had") mais le principe est valable quelles que soient les données (par exemple, un fichier graphique). Pour convertir chaque 24 bits de données d'entrée en 32 bits de sortie, le codage Base 64 divise les 24 bits en 4 morceaux de 6 bits. Le premier problème que nous remarquons est que "Mary had" n'est pas un multiple de 3 octets - il fait 8 octets de long. Pour cette raison, le dernier groupe de bits ne fait que 4 bits de long. Pour y remédier, nous ajoutons deux bits supplémentaires de «0» et rappelons ce fait en mettant un «=» à la fin. Si la chaîne de texte à convertir en Base 64 avait une longueur de 7 octets, le dernier groupe aurait eu 2 bits. Dans ce cas, nous aurions ajouté quatre bits supplémentaires de «0» et nous nous en souviendrions en mettant «==» à la fin.

Dev
la source