IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Binhex amélioré ou lecture binaire


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    Développeur en formation
    Inscrit en
    Juillet 2013
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en formation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2013
    Messages : 300
    Points : 413
    Points
    413
    Par défaut Binhex amélioré ou lecture binaire
    Bonjour,
    j'aurais besoin pour un projet d'une fonction permettant de convertir une valeur binaire telle que :

    >>> fichier=open(chemin,'rb') #'chemin' est évidement à remplacer
    >>> valeur_binaire=fichier.read()

    en chaîne de caractères (str), puis de pouvoir, à partir de cette chaîne, recréer le fichier d'origine.

    En cherchant, j'ai trouvé le module binhex qui correspond (presque) à ce que j'attends :

    >>> from binhex import *
    >>> binhex(source,sortie.txt) #pour fichier vers str (stocké dans un fichier)
    >>> hexbin(source.txt,fichier_à_recréer) #pour str vers fichier

    Le problème est que le fichier txt généré est bien plus lourd que le fichier d'origine. C'est pourquoi je vous demande s'il serait possible d'avoir une sorte de module binhex optimisé qui recréerait des fichiers txt à peu près aussi lourds que l'origine (j'ai remarqué que le fichier généré ne comportait pas d'accents et de symboles spéciaux, voix à suivre). Les applications seraient multiples (fragmentation de fichier pour mails, transfert de données cryptées...). J'ai impérativement besoin d'obtenir une chaîne afin de pouvoir transférer un fichier sous forme de texte transmissible sous n'importe quelle forme !

    J'ai bien sûr pensé au code source de ce module, qui est quasiment imbuvable pour un français (et très peu documenté avec des #) mais surtout qui renvoi vers des modules built-in, bref, c'est assez compliqué pour moi qui ne suis encore que débutant.

    Une autre voix pour le même but serait d'obtenir une version réellement binaire du fichier, je veux dire par là une suite composée de 0 et de 1, une chaîne str. Ce serait vraiment l'idéal pour le cryptage qui en serait simplifié. Il faut évidement pouvoir faire l'action inverse.

    Merci par avance de votre aide .
    Bouddha : Tout n'est qu'illusion en ce bas monde.
    Jésus : Tout est amour divin.
    Einstein : Tout est relatif dans cet espace-temps.
    Moi : Tout est binaire sur ce forum.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    As-tu remarqué le module binascii ? Il offre plusieurs méthodes de transformation de données binaires en caractères ASCII affichables (si j'ai bien compris ta question).

    Mais le résultat sera toujours plus gros que le fichier binaire, vu qu'il s'agit finalement d'une restriction du nombre de valeurs utilisables de chaque octet.
    Par exemple en base64, 64 valeurs sont utilisées, soit 6 bits sur les 8, donc la taille est au minimum multipliée par 8/6, soit 33% d'augmentation. En pratique c'est un peu plus, car des sauts de ligne sont aussi insérés.

    A part compresser le fichier binaire avant de le convertir, il n'y a rien que tu puisse faire.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur en formation
    Inscrit en
    Juillet 2013
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en formation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2013
    Messages : 300
    Points : 413
    Points
    413
    Par défaut
    Merci, je regarde la documentation du module. Si j'ai bien compris, ses fonctions permettent en gros de transformer des variables bytes en str selon différents cryptages ? (par exemple, je dis n'importe quoi : b'0x23' -> 'e').
    Sinon, y-a-t'il un moyen d'obtenir autre chose que ces '0x23' qui sont difficiles à convertir efficacement, le binaire en 0 et 1 dont je parlais (j'ai par exemple un fichier de 500 octets, quand je fais len(chaine_obtenue), j'obtiens 500x8 -> 4000 et je peux bien sûr à partir de cette chaîne retrouver mon fichier d'origine).

    Edit :
    J'ai regardé brièvement le module et voici quelques fonctions qui m'ont intéressé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import binascii
    binascii.b2a_base64(chaîne_issue_de_la_lecture)
    # et on passe d'un truc comme ça :
    # b'RIFF$*\xf1\x02WAVEfmt \x10\x00\x00\x00'
    #à un truc comme ça :
    # b'UklGRiQq8QJXQVZFZm10IBAAAA'
    binascii.a2b_base64(chaine_convertie)
    #qui fait l'inverse
    Ce qui au final revient au même que le module binhex (en effet, len(chaine_convertie)>len(chaîne_issue_de_la_lecture). Ton explication est juste, les solutions sont donc : écrire des fonction transformant par exemple 'ab' en 'é' ou alors en revenir au binaire qui pourra être converti en hexadécimal ect...

    Autre chose (demande de confirmation) :
    quand je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    liste=[]
    for oct in var_obtenue_avec_read :
        liste.append(oct)
    j'obtiens une liste de nombres (qui représentent très probablement la valeur décimale des octets). Ce que je recherche est donc de convertir cette liste en le fichier d'origine.
    Bouddha : Tout n'est qu'illusion en ce bas monde.
    Jésus : Tout est amour divin.
    Einstein : Tout est relatif dans cet espace-temps.
    Moi : Tout est binaire sur ce forum.

  4. #4
    Membre averti
    Homme Profil pro
    Développeur en formation
    Inscrit en
    Juillet 2013
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en formation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2013
    Messages : 300
    Points : 413
    Points
    413
    Par défaut
    Désolé pour le double-post mais il me semblait nécessaire. J'ai réussi à obtenir ce que je voulais (d'une certaine manière). Voici le code simplifié :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # -*-coding :c'est là le hic, je ne sais pas quel encodage choisir :cry:
    f=open(chemin)
    contenu=f.read()
    f.close()#jusque là, ça va
    octets=list()
    for octet in contenu : # c'est là la 1ère partie de la solution, on obtient la valeur
        #de l'octet sous forme d'int
        octets.append(octet)
    #on a à présent une liste des valeurs des octets (si vous avez une solution plus rapide que la boucle for, je suis preneur)
    #mais au lieu de faire ça, on peut faire
    caractères="""abcdefgh......"-'12#éàï""" #je ne vous ai pas mis la chaîne de 256 caractères, mais c'est là que se pose le problème de l'encodage
    for octet in contenu :
        octets.append(caractères[octet]) #là, on obtient une suite de caractères
    Je ne vous mets pas l'inverse, je pense que vous aurez compris. Là où se pose le problème, c'est qu'à partir du moment où la variable caractères contient des caractères spéciaux (é,à,¤...), l'encodage que je n'arrive pas à choisir empêche le script de s'exécuter avec la console et je suis obligé de l'exécuter avec l'IDE (qui est beaucoup plus lent que la console, et c'est gênant pour ce genre de tâches). Quel encodage choisir ?
    Merci par avance de votre réponse.
    Bouddha : Tout n'est qu'illusion en ce bas monde.
    Jésus : Tout est amour divin.
    Einstein : Tout est relatif dans cet espace-temps.
    Moi : Tout est binaire sur ce forum.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Le problème c'est que je ne vois pas où tu veux en venir, ce que tu veux faire. Des encodages comme base64 ou binhex sont généralement utilisés lorsque l'on veut transmettre des données binaires sur un support qui ne gère que le texte ASCII (limité à 7 bits par octets) et/ou qui pourrait transformer certains caractères comme les fin de ligne/tabulations. C'est le cas de l'email, par exemple.

    Toi, tu dis que tu veux convertir de 'bytes' en 'str'. J'ai compris que tu es en Python 3.x. Ce qui veut dire que le type 'str' est en fait de l'unicode. Tu sembles avoir trouvé une séquence de 256 caractères affichables, ce qui te donnera une chaîne 'str' qui contient autant de caractères que ta chaîne 'bytes' contient d'octets. Mais, bien que ce ne soit pas visible directement, elle utilisera plus de mémoire car un caractère unicode prend plus d'un octet.

    Ensuite, le type 'str' ne peut pas être utilisé directement pour la lecture/écriture (que ce soit sur le disque ou sur le réseau), mais doit être (re)transformé en 'bytes'. Je n'ai aucune idée de ce que tu veux faire avec cette variable 'str'. C'est comme si tu voulais transformer ton fichier binaire en un fichier 'texte' qui utiliserait un codec comme utf-8 ou utf-16 (pouvant représenter tout le range unicode) et ne contiendrait que des caractères affichables. Mais même dans ce cas, ton fichier sera plus gros (en octets) que ton fichier binaire d'origine, car il est obligatoire que certains de tes caractères utilisent plus d'un octet, quel que soit le codec utilisé.

    A mon avis, il faut prendre un peu de recul. Pourquoi as-tu besoin de cette conversion ?

  6. #6
    Membre averti
    Homme Profil pro
    Développeur en formation
    Inscrit en
    Juillet 2013
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en formation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2013
    Messages : 300
    Points : 413
    Points
    413
    Par défaut
    Mon projet (et j'en ai déjà fait une partie) est d'écrire un programme permettant :
    - d'exporter un fichier sous forme de texte afin de pouvoir le transférer dans des supports du genre e-mail, forum (ce sont des exemples, ça ne sera pas forcement utile à tout le monde)
    - de coder/décoder des fichiers de manière à ce qu'il soit illisible pour quelqu'un n'ayant pas le code (plus une sorte de clé de cryptage dans mon cas) et que le fichier encodé fasse la même taille que le fichier d'origine
    - de fractionner des fichiers en plusieurs parties (pour transférer en plusieurs fois par e-mail un fichier lourd)
    - de pouvoir compresser un fichier (ce qui ne servira que pour son transport, le fichier obtenu sera illisible)
    (je suis effectivement sous Python 3.3)

    J'ai déjà réussi les 3 premiers objectifs. Le problème posé au départ, je l'ai résolu : une fois qu'on peut transformer puis reformer les bytes, c'est bon.
    Le nouveau problème qui se pose est le suivant : je ne peux ouvrir mon programme qu'avec IDLE (très probablement une histoire d'encodage, le fameux : # -*-coding:encodage -*) qui est plus lent que la console python, et je ne peux donc pas le "compiler" (avec Cx Freeze).

    Alors, pourquoi ai-je besoin de caractères spéciaux ?

    J'en ai besoin pour les 2 premiers objectifs du programme qui utilisent cette chaîne de 256 caractères (à moins que vous n'ayez une autre idée de chaîne de 256 caractères différents) :
    alphabet_ref="""!"#;<=>?@ABCDħĨĩĪīĬĭĮĶķĸĹĺĻļVWXYZ[\]^_`abcdopqrs»¼½¾¿ÀÁÂÃÄ$%&'()*+,-./012JKLMÊËÌÍÎÏÐÑÒNOįİıIJefghijklmnijĴĵPQRSTU56789:ÅÆÇÈÉÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçètuvwxyz{|}~¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶•¸¹ºéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤ34EFGHIĥĦĽľĿŀŁłŃ"""
    Bouddha : Tout n'est qu'illusion en ce bas monde.
    Jésus : Tout est amour divin.
    Einstein : Tout est relatif dans cet espace-temps.
    Moi : Tout est binaire sur ce forum.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Lecture binaire] Problème de conversion
    Par poukill dans le forum C++
    Réponses: 2
    Dernier message: 14/09/2007, 09h34
  2. Lire le format d'images PPM : de la lecture binaire ou texte des fichiers
    Par cladsam dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 08/05/2007, 12h35
  3. lecture binaire sur un flux
    Par zais_ethael dans le forum C++
    Réponses: 9
    Dernier message: 29/08/2006, 01h11
  4. Lecture binaire
    Par Rupella dans le forum C++
    Réponses: 1
    Dernier message: 21/04/2006, 13h43
  5. Réponses: 27
    Dernier message: 12/01/2006, 11h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo