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 :

modifier un octet dans un fichier binaire


Sujet :

Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2016
    Messages : 24
    Points : 11
    Points
    11
    Par défaut modifier un octet dans un fichier binaire
    Bonjour, je ne suis pas sur d'être dans la bonne section du forum mais je tente ma chance

    Je suis actuellement en train d'essayer d'apprendre le langage Python car j'ai besoin de lire et ensuite de modifier un octet dans un fichier binaire et malgré tout ce que j'ai lu jusqu'a maintenant, je ne sais pas du tout comment aborder cela

    Si je sais en qu'elle position est mon octet dans le fichier binaire, comment est ce que je fais pour aller le lire ???

    Et ensuite comment est ce que je peux bien faire pour modifier cet octet toujours a son emplacement dans le fichier ???

    Si quelqu'un pouvais m'aider ca serait sympa ...

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Attention: ce qui suit est sous Python 3 (ce serait un peu différent sous Python 2)

    Imaginons un fichier binaire, par exemple une image. On va chercher un octet "FC" en hexa, et on va le changer en "FD".

    Lecture du fichier en mode binaire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fichier1 = "image.jpg"
    with open(fichier1, "rb") as fs:
        contenu = fs.read() # le contenu est de type "bytes" (=octets)
    Pour chercher l'octet "FC" et le remplacer par "FD":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    octet1 = bytes.fromhex('FC') # octet à chercher
    octet2 = bytes.fromhex('FD') # octet à mettre à la place
    index = contenu.find(octet1)
    if index<0:
        print("Octet non trouvé!")
    else:
        print("Octet cherché se trouve à l'index:", index)
        contenu = contenu[:index] + octet2 + contenu[index+1:]
    La méthode .find cherche la 1ère occurence, mais il y a des arguments supplémentaires qui permettent d'aller plus loin (voir la doc).

    Et on va écrire le résultat dans un nouveau fichier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fichier2 = "image2.jpg"
    with open(fichier2, "wb") as fd:
        fd.write(contenu)
    Et c'est tout!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre à l'essai
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2016
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Merci pour ta réponse mais je ne souhaite pas chercher l'octet, je sais par exemple que mon octet a la position 24 dans le fichier donc je souhaite, lire mon octet qui est a la position 24 et je souhaite ensuite modifier sa valeur

    Ta solution pourrait être très bien mais j'ai peur que si un autre octet ait la même valeur, qu'il s'en retrouve modifié alors que ce n'est pas ce que je souhaite

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par poseidon31 Voir le message
    Si je sais en qu'elle position est mon octet dans le fichier binaire, comment est ce que je fais pour aller le lire ???

    Et ensuite comment est ce que je peux bien faire pour modifier cet octet toujours a son emplacement dans le fichier ???
    C'est un exo. à faire avec la console Python.
    On commence par créer un fichier binaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> f = open('test.dat', 'wb')
    >>> f.write(b'01234567890123456789')
    20
    >>> f.close()
    Puis on le réouvre "en mise à jour":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    >>> f = open('test.dat', 'rb+')
    Puis on a deux fonctions primitives pour contrôler la position du prochain octet à lire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> f.tell()  # la position courante
    0
    >>> f.seek(5) # pour se déplacer (par défaut depuis le début du fichier).
    Si on lit un octet, la position de l'octet suivant à lire sera +1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> f.read(1)
    b'5'
    >>> f.tell()
    6
    >>>
    donc pour "écraser" après avoir vérifier que, il faut "repositionner" avec .seek:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> f.seek(-1, 1)
    5
    >>> f.write(b'X')
    1
    Puis on ferme le fichier et on regarde si la modification a été prise en compte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> f.close()
    >>> open('test.dat', 'rb').read()
    b'01234X67890123456789'
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre à l'essai
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2016
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Lol, ca me parait pas mal, je vais prendre un peu de temps pour me pencher sur cette solution et je vous tiens au courant

    Sinon, voici un exemple de mon fichier binaire :

    63 55 1D B6 E2 A3 78 7E 89 2A B6 BF EF 1A AF B2
    00 15 00 15 00 00 00 00 00 00 00 00 00 00 00 56
    00 1F 00 1F 00 00 00 00 00 00 00 00 00 00 00 57
    55 57 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    C0 33 8F A4 F9 6A 78 77 89 0F 34 7A F2 B8 76 D2
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
    55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    89 44 06 3D 47 4E 78 78 88 00 FD DE 79 31 11 3D

    Je dois lire le 55 qui est au début de la 4eme ligne et comme vous pouvez le constater, mon deuxième octet est également un 55 que je ne veux pas toucher

  6. #6
    Membre à l'essai
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2016
    Messages : 24
    Points : 11
    Points
    11
    Par défaut suite
    Bonjour,

    Bon je reviens sur cette discussion car je suis a nouveau bloqué, j'arrive a lire l'octet donc j'ai besoin avec ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    f = open('test.dat', 'rb+')
    f.seek(5) 
    tag=f.read(1)
    f.tell()
    Mais j'obtiens en résultat :b'\xa3'

    Hors j'aurais besoin de convertir cette valeur en décimal pour pouvoir intervenir dessus (l'incrémenter ou la décrémenter) et ensuite la reconvertir en hexa pour la réécrire dans le fichier .dat

    Est ce que quelqu'un pourrait me dire comment on fait ca ???

  7. #7
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Citation Envoyé par poseidon31 Voir le message
    Bonjour,

    f = open('test.dat', 'rb+')
    f.seek(5)
    tag=f.read(1)
    f.tell()

    Mais j'obtiens en résultat :b'\xa3'
    Bonjour

    tu trouveras ton bonheur avec le module struct.

    Utilise 'b' ou 'B' selon que ton entier sur 1 octet est signé ou pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> octet = b'\xa3'
    >>> unpack('b', octet)
    (-93,)
    >>> unpack('B', octet)
    (163,)
    Attention : unpack retourne systématiquement un tuple
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  8. #8
    Membre à l'essai
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2016
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Merci Plxpy, je viens d'essayer mais j'ai ce message d'erreur :

    NameError: name 'unpack' is not defined

  9. #9
    Membre à l'essai
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2016
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Et aussi je voulais savoir, qu'elle est la commande ensuite pour faire l'inverse, passer du décimal a l'hexa ?

    Merci

  10. #10
    Membre à l'essai
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2016
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2016
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Finalement j'ai un peu avancé mais j'ai encore un autre souci
    Quand j'essaie de lire une valeur composé de deux octets j'ai ce message :

    struct.error: unpack requires a bytes object of length 1

    Comment est ce que je peux lui dire que ma valeur est composé de deux octets ?

  11. #11
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Citation Envoyé par poseidon31 Voir le message
    Et aussi je voulais savoir, qu'elle est la commande ensuite pour faire l'inverse, passer du décimal a l'hexa ?

    Merci
    Tout est dans la documentation de struct (lien donné précédemment). Faut un peu lire : pack, unpack, les formats (b, B, I, i, h, etc...). Si tu veux t'attaquer à des modifications de la sorte (aller patcher un fichier binaire), faut investir un minimum.
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

Discussions similaires

  1. Lire des octets dans un fichier binaire
    Par DiverSIG dans le forum Entrée/Sortie
    Réponses: 12
    Dernier message: 19/01/2009, 10h22
  2. Remplacer un octet dans un fichier binaire
    Par gedeon555 dans le forum VBScript
    Réponses: 0
    Dernier message: 17/08/2008, 12h59
  3. Réponses: 2
    Dernier message: 27/06/2006, 14h33
  4. modifier une variable dans un fichier
    Par Guismay dans le forum Langage
    Réponses: 7
    Dernier message: 11/09/2005, 19h46
  5. [LG]ecriture dans un fichier binaire
    Par jsaviola dans le forum Langage
    Réponses: 3
    Dernier message: 26/12/2003, 17h30

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