Récupération de fichier binaire contenu à l'aide de Javascript, base64 encode et de renverser le décoder à l'aide de Python

Je suis en train de télécharger un fichier binaire en utilisant XMLHttpRequest (à l'aide d'une récente Webkit) et en base64 encode son contenu à l'aide de cette fonction simple:

function getBinary(file){
    var xhr = new XMLHttpRequest();  
    xhr.open("GET", file, false);  
    xhr.overrideMimeType("text/plain; charset=x-user-defined");  
    xhr.send(null);
    return xhr.responseText;
}

function base64encode(binary) {
    return btoa(unescape(encodeURIComponent(binary)));
}

var binary = getBinary('http://some.tld/sample.pdf');
var base64encoded = base64encode(binary);

Comme une note de côté, tout ce qui précède est Javascript standard des choses, y compris btoa() et encodeURIComponent(): https://developer.mozilla.org/en/DOM/window.btoa

Cela fonctionne assez bien, et je peux même décoder le base64 contenu à l'aide de Javascript:

function base64decode(base64) {
    return decodeURIComponent(escape(atob(base64)));
}

var decodedBinary = base64decode(base64encoded);
decodedBinary === binary //true

Maintenant, je veux décoder le base64 contenu à l'aide de Python qui consomme de l'chaîne JSON pour obtenir le base64encoded de la chaîne de valeur. Naïvement, c'est ce que je fais:

import urllib
import base64
# ... retrieving of base64 encoded string through JSON
base64 = "77+9UE5HDQ……………oaCgA="
source_contents = urllib.unquote(base64.b64decode(base64))
destination_file = open(destination, 'wb')
destination_file.write(source_contents)
destination_file.close()

Mais le fichier n'est pas valide, ressemble à l'opération messaed avec UTF-8, de codage ou de quelque chose qui n'est pas encore clair pour moi.

Si j'essaie de décoder UTF-8 table des matières avant de les mettre dans le fichier de destination, une erreur est générée:

import urllib
import base64
# ... retrieving of base64 encoded string through JSON
base64 = "77+9UE5HDQ……………oaCgA="
source_contents = urllib.unquote(base64.b64decode(base64)).decode('utf-8')
destination_file = open(destination, 'wb')
destination_file.write(source_contents)
destination_file.close()

$ python test.py
//...
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 0: ordinal not in range(128)

Comme une note de côté, voici une capture d'écran de deux représentations textuelles d'un même fichier; sur la gauche: l'original; sur la droite: celui qui a été créé à partir de la base64-décodé chaîne: http://cl.ly/0U3G34110z3c132O2e2x

Est-il connu astuce pour contourner ces problèmes avec l'encodage lors de la tentative de recréer le fichier? Comment voulez-vous atteindre vous-même?

De l'aide ou de l'indice appréciée 🙂

  • Comme une note de côté, j'ai essayé de jouer avec le codecs module pour écrire le fichier de destination à l'aide de la 'utf-8' codec avec pas de chance, mais j'ai du loupé quelque chose quelque part.
  • Ce qui est étrange, comme \ufffd est très spécial: fileformat.info/info/unicode/char/fffd/index.htm
  • Que suppose la base64encode() fonction que j'utilise est impossible de convertir certains caractères... La chose étrange est que l'opération inverse fonctionne parfaitement en javascript...
  • Avez-vous essayer de vider les premiers octets de valeurs à différentes étapes. Ressemble à l'une ou à votre bibliothèque est trop intelligent et ne pas faire la convertion au niveau octet. Je suggère la création d'un simple fichier texte UTF-8 avec >255 points de code et analyser manuellement les octets de valeurs à chaque étape. Vous devriez arrêter où est l'erreur.
  • Je n'utilise pas de bibliothèque malheureusement... JS trucs (btoa(), encodeURIComponent() et unescape()) sont standard. Même par la partie Python, rien d'autre que stdlib substance utilisée... je vais enquêter sur l'étrange Octets valeurs de mettre ce qui semble être une vraie douleur 🙁
InformationsquelleAutor NiKo | 2011-09-10