Python: Ignore 'Incorrect rembourrage' erreur lorsque le décodage en base64
J'ai des données qui est encodé en base64 que je veux convertir en arrière binaire, même si il y a une marge d'erreur. Si j'utilise
base64.decodestring(b64_string)
il soulève une "Incorrect rembourrage' erreur. Est-il une autre voie?
Mise à JOUR: Merci pour tous les commentaires. Pour être honnête, toutes les méthodes mentionnées sonnait un peu touché
et miss j'ai donc décidé d'essayer d'openssl. La commande suivante travaillé un régal:
openssl enc -d -base64 -in b64string -out binary_data
- Vous avez réellement ESSAYEZ d'utiliser
base64.b64decode(strg, '-_')
? C'est a priori, sans vous déranger à fournir toutes les données de l'échantillon, le plus probable Python solution à votre problème. Les méthodes proposées ont été DEBUG suggestions, NÉCESSAIREMENT "hit and miss" compte tenu de la rareté de l'information fournie. - Machin: Oui, j'ai essayé votre méthode mais il ne fonctionne pas. Les données confidentielles de l'entreprise.
- Excuse mon ignorance, mais qu'est-ce que une marge d'erreur? Je suis un dès maintenant et ne sais pas pourquoi
- Essayez
base64.urlsafe_b64decode(s)
- Pourriez-vous fournir le résultat de ceci:
sorted(list(set(b64_string)))
s'il vous plaît? Sans rien dévoiler de l'entreprise confidentielle, qui devrait révéler les caractères qui ont été utilisés pour coder les données d'origine, qui à son tour peut fournir suffisamment de données pour fournir une non-hit-or-miss solution. - Oui, je sais que c'est déjà résolu, mais, pour être honnête, la openssl solution aussi des sons hit-or-miss pour moi.
- Oups, ma suggestion reproduit la une de @JohnMachin ci-dessous. Jamais l'esprit!
Vous devez vous connecter pour publier un commentaire.
Comme dit dans d'autres réponses, il y a différentes façons dans lequel les données base64 peut être corrompu.
Cependant, comme Wikipédia dit, de retirer le rembourrage (les caractères '=' à la fin des données encodées en base64) est "sans perte":
Donc, si ce est vraiment la seule chose de "mal" avec votre base64 de données, le remplissage peut juste être rajoutés. J'ai trouvé ceci pour être en mesure d'analyser les "données" Url dans WeasyPrint, dont certains ont été base64 sans rembourrage:
De Tests pour cette fonction: weasyprint/tests/test_css.py#L68
str(data)
base64.decodestring
a été supprimée pourbase64.decodebytes
dans Py3, mais pour la version de compatibilité mieux utiliserbase64.b64decode
.base64
module n'ignore pas valide non base64 caractères dans le champ de saisie, vous devez d'abord normaliser les données. Supprimer tout ce qui n'est pas une lettre, d'un chiffre/
ou+
, et puis ajoutez le rembourrage.Juste ajouter rembourrage en tant que de besoin. Attention de Michael avertissement, cependant.
Si il y a une marge d'erreur, cela signifie probablement que votre chaîne est endommagée; base64 les chaînes doivent avoir un multiple de quatre de longueur. Vous pouvez essayer d'ajouter le rembourrage personnage (
=
) de vous-même pour rendre la chaîne d'un multiple de quatre, mais il faut déjà que, à moins que quelque chose est malIncorrecte"rembourrage" peut signifier non seulement manquant "remplissage", mais aussi (croyez-le ou pas) incorrecte "rembourrage".
Si suggéré "l'ajout de rembourrage" méthodes ne fonctionnent pas, essayez de supprimer certains de fuite octets:
Mise à jour: Tout bidouiller l'ajout de rembourrage ou de retirer éventuellement mal d'octets à partir de la fin doit être fait APRÈS le retrait de n'importe quel espace, sinon les calculs de longueur va être bouleversé.
Ce serait une bonne idée si vous nous avez montré une (courte) de l'échantillon des données que vous avez besoin de récupérer. Modifier votre question et copier/coller le résultat de
print repr(sample)
.Mise à jour 2: Il est possible que le codage a été fait dans une url de manière sécuritaire. Si c'est le cas, vous serez en mesure de voir moins et caractères de soulignement dans vos données, et vous devriez être capable de le décoder en utilisant
base64.b64decode(strg, '-_')
Si vous ne pouvez pas voir moins et caractères de soulignement dans vos données, mais il peut voir plus et caractères barre oblique, alors vous avez un autre problème, et peut-être besoin du complément de remplissage ou de supprimer des-trucs astuces.
Si vous pouvez le voir rien de moins, le trait de soulignement, plus et slash dans vos données, alors vous avez besoin pour déterminer les deux autres caractères; ils seront ceux qui ne sont pas dans [A-Za-z0-9]. Ensuite, vous aurez besoin d'expérimenter pour voir l'ordre dans lequel ils doivent être utilisés dans le 2ème argument de
base64.b64decode()
Mise à jour 3: Si vos données est "confidentiel":
(a) vous devez le dire à l'avant
(b) nous pouvons explorer d'autres avenues dans la compréhension du problème, qui est très susceptible d'être liée à ce que les caractères sont utilisés à la place de
+
et/
dans le codage de l'alphabet, ou par d'autres mise en forme ou des corps étrangers caractères.Une telle solution serait d'examiner ce que les non-"standard" où les personnages sont dans vos données, par exemple
Utilisation
De crédit va à un commentaire quelque part ici.
Je n'ai pas de rep pour le commentaire, mais une chose à noter est que (au moins en Python 3.x) en base64.b64decode tronque toute rembourrage supplémentaire à condition qu'il existe suffisamment en premier lieu.
Donc, quelque chose comme:
b'abc='
fonctionne tout aussi bien queb'abc=='
.Ce que cela signifie est que vous pouvez simplement ajouter le nombre maximum de caractères de remplissage que vous avez besoin—qui est de trois (
b'==='
)—et base64 va tronquer tout ceux qui sont inutiles.En gros:
est plus propre que
binascii.Error: Invalid base64-encoded string: number of data characters (5) cannot be 1 more than a multiple of 4
. Merci pour cela!Consultez la documentation de la source de données que vous essayez de décoder. Est-il possible que vous vouliez dire à l'utilisation
base64.urlsafe_b64decode(s)
au lieu debase64.b64decode(s)
? C'est une des raisons que vous pourriez avoir vu ce message d'erreur.C'est par exemple le cas pour les différentes Api Google, comme Google l'Identité d'une Trousse à outils et Gmail charges.
urlsafe_b64decode
nécessite également un rembourrage.base64.urlsafe_b64decode
.Ajoutant le rembourrage est plutôt... laborieux. Voici la fonction que j'ai écrit avec l'aide des commentaires dans ce fil, ainsi que la page du wiki pour en base64 (il est étonnamment utile) https://en.wikipedia.org/wiki/Base64#Padding.
Il y a deux façons de corriger les données d'entrée décrit ici, ou, plus précisément, et en conformité avec l'OP, pour rendre module Python base64 est b64decode méthode de mesure de traiter les données d'entrée pour quelque chose sans lever une exception interceptée:
Si cela soulève une exception, alors
je. L'attraper par try/except,
ii. (R?)Bande tout = caractères à partir de la saisie de données (N. B. cela peut ne pas être nécessaire),
iii. Ajouter Un== pour l'entrée de données (A== par P== travail),
iv. Appel en base64.b64decode(...) avec A==-annexé données d'entrée
Le résultat de la question 1. ou de l'Article 2. ci-dessus donnera le résultat souhaité.
Mises en garde
Cela ne garantit pas la décodé résultat sera à ce qui avait été codé, mais il va (parfois?) donner l'OP suffisant pour travailler avec:
Voir Ce que nous savons et Hypothèses ci-dessous.
TL;DR
De quelques tests rapides de base64.b64decode(...)
il semble qu'il ignore non[A-Za-z0-9+/] de caractères; qui comprend ignorant =s sauf ils sont le dernier caractère(s) dans un analysée groupe de quatre, auquel cas la =s résilier le décodage (a=b=c=d= donne le même résultat que abc= et a==b==c== donne le même résultat que ab==).
Il apparaît également que tous de caractères sont ignorés après le point où en base64.b64decode(...) se termine le décodage comme par exemple un = en tant que quatrième dans un groupe.
Comme indiqué dans plusieurs commentaires ci-dessus, il y a zéro ou un, ou deux, =s de rembourrage, à la fin des données d'entrée pour quand le [nombre de analysée personnages à ce point modulo 4] la valeur est 0, ou 3, ou 2, respectivement. Ainsi, à partir des éléments 3. et 4. ci-dessus, en y ajoutant deux ou plus =s pour les données d'entrée va corriger tout [Incorrecte rembourrage] problèmes dans ces cas.
CEPENDANT, décodage ne peut pas gérer le cas où le [nombre total de analysée caractères modulo 4] est 1, car il faut au moins deux caractères codés pour représenter la première décodé octet dans un groupe de trois décodé octets. Dans de l'onucorrompu codée des données d'entrée, ce [N modulo 4]=1 cas n'arrive jamais, mais que l'OP a déclaré que les caractères peuvent être manquantes, il pourrait se produire ici. C'est pourquoi, simplement en ajoutant =s ne fonctionne pas toujours, et pourquoi ajoutant Un== fonctionnera lors de l'ajout == ne pas. N. B. à l'Aide de [A] est tout sauf arbitraire: il ajoute seulement à zéro des bits à la décodé, qui peut être ou ne pas être correcte, mais l'objet ici n'est pas de l'exactitude mais la fin en base64.b64decode(...) sans exceptions.
Ce que nous savons de l'OP et surtout les commentaires ultérieurs est
Base64 données d'entrée
A-Z, a-z, 0-9; +; /; = est de rembourrage. C'est confirmé, ou au moins
suggéré par le fait que
openssl enc ...
œuvres.Hypothèses
Github
Ici est un wrapper pour mettre en œuvre cette solution:
https://github.com/drbitboy/missing_b64
Simplement ajouter d'autres caractères tels que "=" ou toute autre et d'en faire un multiple de 4 avant d'essayer de décodage de la cible de la chaîne de valeur. Quelque chose comme;
Dans le cas où cette erreur provient d'un serveur web: Essayez de l'encodage de l'url de votre post de valeur. J'ai été Poster par "curl" et découvert que je n'étais pas d'url de codage de mon base64 valeur, de sorte que les caractères comme "+" n'ont pas échappé à l'url du serveur web-décoder la logique automatiquement couru url-décoder et converti + espaces.
"+" est valide base64 caractère et peut-être le seul personnage qui obtient mutilé par un inattendu url-décoder.
Dans mon cas, j'ai fait face à cette erreur lors de l'analyse d'un courrier électronique. J'ai eu l'attachement en base64 de la chaîne et de l'extraire via ré.de recherche. Finalement, il y avait une étrange supplémentaires sous-chaîne à la fin.
Lorsque j'ai supprimé
--_=ic0008m4wtZ4TqBFd+sXC8--
et de la bande de la chaîne, puis l'analyse a été fixé.Donc mon conseil est de vous assurez que vous êtes un décodage correct base64 chaîne.
Vous devez utiliser
Par défaut, le altchars sont
'+/'
.