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 :

Ouvrir un fichier en mode binaire.


Sujet :

Python

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 8
    Points
    8
    Par défaut [RESOLU] Ouvrir un fichier en mode binaire.
    Bonjour à tous...

    C'est une question qui est déjà tombée sur ce forum et ailleurs, et qui est (un peu) documentée dans la doc. Mais tous les essais que je fais se soldent immanquablement par des échecs...

    Mon problème est assez simple : je veux lire un fichier quelconque en binaire, et plus précisément pouvoir remplir une suite de listes [0..95] par les valeurs 0/1 (soit 12 octets dans ma liste).

    Après avoir importé les modules ad hoc, un classique :
    f = open (fichier, "rU")
    ou f = open (fichier, "rb")
    ne me donnent rien : si j'appelle f.read(1), il me renvoie un CHAR. Le mieux que j'arrive à faire, c'est prendre la valeur ASCII et la convertir en binaire, mais c'est lent et pas du tout satisfaisant. Et ça ne me permet pas d'écrire.

    Comment, donc, arriver à ouvrir en R (ou en W, mais pas en même temps) un fichier en mode binaire ? Et tout ça sous XP, Python 2.4.3.


    Merci à vous,

    Christophe

    P.S. : et encore, tout ça c'est après avoir réglé l'habituel problème du "from os import *" vx "import os"

  2. #2
    Membre expérimenté Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Points : 1 728
    Points
    1 728
    Par défaut
    Bonjour,

    le module struct devrait repondre à ton besoin.

    voilà, voilà....
    "Etre conscient de la difficulté permet de l'éviter.."
    Lao-Tseu.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    J'ai déjà essayé le module binascii (également renseigné dans la doc python), mais sans résultat. En fait, ça marchait bien pour sortir de l'hexa, mais impossible d'obtenir quelque chose avec la fonction qui aurait du me renvoyer du binaire (a2b_base64, qui me renvoyait 'incorrect padding', de mémoire).

    J'ai donc récupéré une fonction qui me convertit un ord(char) en sa valeur binaire.

    Mais ce n'est pas ce que je veux... C'est trop lent, et ça ne marche qu'en lecture.
    Je veux ouvrir directement le fichier en binaire, càd, que read() me renvoie un 0/1. (Déjà que le type booléen n'existe pas... c'est pas gagné.)


    Merci...

    Christophe

  4. #4
    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
    Bonjour,

    Ce qu'on entend généralement par fichier binaire, c'est un fichier ou les 256 valeurs de chaque octet sont utilisées directement pour encoder des données, par opposition aux fichiers textes où les données du fichier sont censées représenter des caractères et sont soumises à une interprétation (par exemple, caractère de fin de ligne, tabulation,...).

    Cela ne veut pas dire que le langage fournit un accès direct aux bits individuels, ce qui n'est jamais le cas (même en assembleur!), car la plus petite zone adressable en mémoire est l'octet. Il y a moyen de la faire en jonglant avec les opérations "bit à bit" (&, |, <<, >>, ~), mais ça ne sera pas super rapide en Python.

    Par exemple, on peut convertir le contenu du fichier entier en un seul entier très long (vu que la taille des entiers n'est pas limitée en Python) et utiliser les opérateurs mentionnés ci-dessus pour extraire les bits qui nous intéressent, mais il faut faire attention à ne pas perdre les bits à 0 en fin de fichier qui deviendraient les bits de poids fort de l'entier...

    Ah et le type booléen existe bien en Python ! Mais ne crois pas qu'un booléen soit encodé sur 1 bit ! (je ne sais pas exactement combien, mais ça ne m'étonnerait pas qu'il soit encodé sur 32 ou 64 bits).

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    D'accord avec dividee: l'ouverture d'un fichier en "binaire" ne veut jamais dire qu'on a accès aux bits, mais qu'on n'interprète pas les caractères qui ont une signification particulière en édition de texte (retour charriot, tabulation, ...).


    Sur ce plan, Python fait son boulot et il suffit de le voir sur un petit exemple (j'ai pris une partie du 1er message):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    s="""C'est une question qui est déjà tombée sur ce forum et ailleurs, et qui est (un peu) documentée dans la doc. Mais tous les essais que je fais se soldent immanquablement par des échecs...
     
    Mon problème est assez simple : je veux lire un fichier quelconque en binaire, et plus précisément pouvoir remplir une suite de listes [0..95] par les valeurs 0/1 (soit 12 octets dans ma liste)."""
    Création d'un fichier contenant exactement les octets de la chaîne s (et pas plus):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    f = open("ftest.txt",'wb')
    f.write(s)
    f.close()
    Après cela, on peut vérifier avec un éditeur hexadécimal que le contenu du fichier est bien l'exacte contenu de s en valeur et en longueur (nombre d'octets).

    Lecture du contenu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    f = open("ftest.txt",'rb')
    x=f.read()
    f.close()
    On constate qu'on a récupéré l'exacte contenu du fichier en valeur et en longueur (nombre d'octets)

    Autre exemple, plus "binaire": on fabrique 1024 octets avec des valeurs d'octet au hasard:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    import random
     
    s=""
    for i in xrange(0,1024):
        c=random.randint(0,255)
        s+="%c" % c
    Si on applique les instructions précédentes, on voit qu'on récupère bien l'exacte contenu de la chaîne d'origine. Et on dispose en plus des facilités de traitement des chaines Python. Par exemple:
    => s[256:512] renvoie bien le 2ème paquet de 256 octets.
    => d=[ord(c) for c in list(s[256:512])] renvoie la même chose sous forme d'une liste d'octets convertis en entier.
    => sur les listes d'entiers, on peut faire tous les traitements binaires qu'on veut. Par exemple, for x in d: x = x>>1 divise par 2 tous les octets de la liste d'entier d.
    => "".join([chr(c) for c in d]) renvoie une chaîne à partir d'une liste d'entiers d
    etc...

    Après, si on veut faire un traitement binaire, on peut utiliser struct, mais on peut aussi développer toutes les fonctions qu'on veut. Python est tout de même très rapide.

    Tyrtamos
    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

  6. #6
    Membre expérimenté Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Points : 1 728
    Points
    1 728
    Par défaut
    Bonjour,

    Quel est l'interêt de recuperer les valeurs binaires de chaque octet?
    Pour voir les bits contenus dans ton fichier?

    Pöur travailler sur les bits, tu n'as pas besoin d'obtenir une representation binaire sous forme de 0 et de 1 (True, False), tu peux simplement utiliser les operateurs binaires (& || )
    "Etre conscient de la difficulté permet de l'éviter.."
    Lao-Tseu.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Merci pour vos (utiles) éclaircissements... et notamment pour l'explication de ce qu'on entend par "fichier binaire". Effectivement, vu comme ça, les tests que j'ai fait en open ("fichier", "rb") fonctionnaient parfaitement
    En attendant, c'est bien ce que je cherche : récupérer char(13), et non \n, par exemple.

    Remarque pertinente aussi sur le fait que la plus petite zone adressable, c'est l'octet.
    Je n'ai donc pas de possibilité plus perfomante que :
    - ouvrir en RB
    - lire chaque caractère
    - prendre ord(char)
    - convertir cette valeur en binaire
    - la formater pour qu'elle tienne sur 8 bits (si je convertis chr(13), j'ai 1101 et non 00001101)
    - rentrer ça dans ma liste [0, 0, 0, 0, 1, 1, 0, 1] à raison de n octets par liste.
    Et faire l'opération inverse pour réécrire un fichier.

    Bon. Je sais pas si ça va être rapide tout ça quand je vais ouvrir un fichier de quelques Mo...

    @ pacificator : Si je cherche à récupérer les valeurs des bits et à les ranger dans une liste, c'est pour essayer un petit algorithme de crypto. DES travaille aussi avec les octets.
    Je ne cherche pas à faire quelque chose d'aussi aboutit ni aussi puissant, en fait j'essaye juste d'approfondir un peu un algorithme que j'avais fait et qui travaillait sur la base des ord(char) lues dans le fichier.
    Voilà...

    Merci pour vos réponses.


    ##
    Christophe

  8. #8
    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
    Citation Envoyé par _christophe_ Voir le message
    @ pacificator : Si je cherche à récupérer les valeurs des bits et à les ranger dans une liste, c'est pour essayer un petit algorithme de crypto. DES travaille aussi avec les octets.
    Même dans un cas comme celui-là, on ne "décompacte" jamais les octets en une liste de bits comme tu veux le faire, on travaille directement sur les octets en utilisant des masques, décalages,etc. En "décompactant" tes bits en entiers, chaque "bit" occupera en réalité 32 bits, donc l'utilisation mémoire de ta liste sera la taille du fichier multipliée par 32.

    On peut éventuellement construire une classe qui donne accès aux bits indivuels. On appelle généralement cela un bitfield (champ de bits); en Python cela pourrait être un container qui implémente les méthodes __getitem__, __setitem__, __getslice__, etc. comme s'il s'agissait d'une liste de bits, mais dans la représentation interne on ne décompactera pas les bits, on utilisera des masques & décalages... Mais ça demande pas mal de travail pour avoir une implémentation correcte & efficace. Le C est plus adapté pour ce genre de boulot, étant un langage de plus bas niveau.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Oups

    Je crois qu'il n'y a rien à ajouter à ça, c'est limpide.
    Merci d'avoir attiré mon attention sur ce point (augmentation de l'utilisation mémoire), j'étais parti dans une fausse direction en voulant justement me simplifier la tâche en évitant l'utilisation des masques.

    Je vais m'orienter vers la construction de cette classe.
    Merci.


    ##
    Christophe

  10. #10
    Membre habitué Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Points : 131
    Points
    131
    Par défaut
    je relance le sujet, car pour moi ce n'est pas limpide.
    ;-)

    je voudrais lire un fichier binaire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    f = open("toto.bin", "rb")
    data = f.read()
    print data, type(data)
    f.close()
    mon probleme, c'est que data est un 'string',
    et je n'arrive pas a le convertir.

    par ailleurs, j'arrive a lire le fichier avec matlab
    un truc du genre : x = read(f, fmt="int16")

    je ne trouve pas d'equivalent en python.

    si une ame charitable voulait bien "se fendre" d'un exemple concret,
    je lui en serais tres reconnaissant.

    merci d'avance.

  11. #11
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Ce n'est pas anormal qu'en lisant un fichier binaire quelconque on récupère une chaîne de caractères: il faut bien que les octets du disque soit portés par quelque chose. Mais ces caractères sont effectivement des octets (0 -> 255) et ne sont pas forcément imprimables.

    Pour transformer un caractère en entier et un entier en caractère, on utilise chr() et ord(). Mais attention pour les 16 bits: comme Python est multi-plateforme, il faudra savoir si l'octet de poids fort se trouve en 1er ou en dernier selon la machine.

    Ce faisant voilà un petit exemple que je t'ai monté. Tu verras 2 petites fonctions qui transforment un entier 16 bits en une chaîne de 2 octets ainsi que le contraire. Ici, le poids fort est en dernier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    from random import randint
     
    def int2chr(nb):
        return chr(nb%256)+chr(nb//256)
     
    def chr2int(ch):
        return ord(ch[0])+ord(ch[1])*256
     
    # on fabrique une liste de 256 valeurs entières sur 16 bits (0 -> 65535)
    L=[]
    for i in xrange(0,256):
        L.append(randint(0,65535))
     
    # on transforme ces valeurs en chaîne de caractères
    ch=''
    for i in xrange(0,256):
        ch+=int2chr(L[i])
     
    # on enregistre cette chaîne sur disque
    f = open('toto.bin','wb')
    f.write(ch)
    f.close()
     
    # on relit le fichier
    f = open('toto.bin','rb')
    x = f.read()
    f.close()
     
    # Et on transforme la chaîne de caractère lue en liste de nombres 16 bits
    R=[]   
    for i in xrange(0,512,2):
        R.append(chr2int(x[i:i+2]))
     
    # Vérification: on doit avoir les valeurs de L identiques avec celles de R
    for i in xrange(0,256):
        if L[i]!=R[i]:
            print "erreur"
     
    # Et, bien sûr, il n'y a pas d'affichage d'erreur!
    Ok?

    Tyrtamos
    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

  12. #12
    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
    @KINENVEU:
    Ton problème n'est pas le même que celui de christophe, tu peux utiliser la solution de tyrtamos ou le module struct (avec, dans ton cas, le type 'short' ou 'unsigned short').

    @christophe:
    Ceci pourrait te convenir:
    http://cobweb.ecn.purdue.edu/~kak/di...ector-1.4.html

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Merci dividee, j'ai lu avec intérêt la documentation liée cette classe BitVector.
    Mais on se retrouve avec le même problème de mémoire que tu soulignais avec justesse, il me semble...

    Je me servirais de cette classe si je ne m'en sors pas bien avec les masques.
    Merci...

    @ KINENVEU : Ce que t'as répondu tyrtamos me semble complet, AMHA, mais je me permets d'ajouter mon petit grain de sel
    Tu t'en sortiras peut être mieux pour les conversions si tu met ce code-ci à la place du tien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    f = open("toto.bin", "rb")
    while 1:
         data = f.read(1)
         if data == "" : break
         print data, type(data), ord(data)
    f.close()
    J'ai demandé à f.read(1) de ne me renvoyer qu'un seul caractère, qui est toujours un STR, comme l'affichage te le prouveras, mais que tu peux traiter comme un CHAR, donc avec ORD() qui te renverras l'entier associé en ASCII.

    A titre d'exemple, pour un fichier qui contiendrait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Ceci est un essai
    123
    ô
    Il me retourne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    C <type 'str'> 67
    e <type 'str'> 101
    c <type 'str'> 99
    i <type 'str'> 105
      <type 'str'> 32
    e <type 'str'> 101
    s <type 'str'> 115
    t <type 'str'> 116
      <type 'str'> 32
    u <type 'str'> 117
    n <type 'str'> 110
      <type 'str'> 32
    e <type 'str'> 101
    s <type 'str'> 115
    s <type 'str'> 115
    a <type 'str'> 97
    i <type 'str'> 105
     
    <type 'str'> 13
     
    <type 'str'> 10
    1 <type 'str'> 49
    2 <type 'str'> 50
    3 <type 'str'> 51
     
    <type 'str'> 13
     
    <type 'str'> 10
    ô <type 'str'> 244
    On observe bien les retours chariots et saut de ligne, resp. 10 et 13.
    J'espère que tout ceci t'aura éclairé les idées...


    ##
    Christophe

  14. #14
    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
    Citation Envoyé par _christophe_ Voir le message
    Merci dividee, j'ai lu avec intérêt la documentation liée cette classe BitVector.
    Mais on se retrouve avec le même problème de mémoire que tu soulignais avec justesse, il me semble...
    Non; cf la doc:
    The BitVector class for a memory-efficient packed representation of bit arrays and for logical operations on such arrays.

    Il utilise comme représentation interne un array de 'short' de 16 bits. Il te permet de le manipuler comme si c'était un array de bits, mais en interne il fait des opérations de masques & décalages pour traduire ces accès en manipulations sur un array de short.

    Pour témoin cette ligne extraite du code source, qui retourne le bit en position posn dans le champ de bits:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return ( self.vector[posn//16] >> (posn&15) ) & 1

  15. #15
    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
    Pour compléter mon post précédent:
    C'est vrai que le bit extrait est retourné sous forme d'un int et prend donc beaucoup de place, mais l'idée c'est que tu ne dois pas extraire tous les bits en même temps, et tu peux utiliser des slices (la notation bv[start:end]) pour extraire/assigner plusieurs bits consécutifs dans un int...

  16. #16
    Membre habitué Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Points : 131
    Points
    131
    Par défaut
    tout d'abord, merci pour votre aide, j'ai pu tester plein de trucs.

    j'avais deja essayer avec la fonction "ord", mais sans succes car je ne travaillais qu'avec un seul byte.

    j'ai donc reessaye avec une lecture sur 2 bytes et avec le poid sur le second,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ch = f.read(2)
    i = ord(ch[0])+ord(ch[1])*256
    ca semble ne marcher que sur les entiers non signe.
    et je n'ai pas trouve comment avoir le signe.

    donc je suis reparti sur le module struct
    j'avais egalement deja essaye mais sans succes,
    car comme un gros boulet, je n'avais pas trouve le bon format.

    j'ai donc reessayer avec le format "short"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    import struct
    f = open("toto.bin", 'rb')
    fmt = "h" # short
    s = struct.calcsize(fmt)
    print "s", s
    x = []
    while True:
      c = f.read(s)
      if (len(c) != s): break
      a = struct.unpack(fmt, c)[0]
      x.append(a)
    f.close()
    et la ca marche impeccable !!!


    merci a tous de m'avoir aide.

  17. #17
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Pour KINENVEU:

    Voici mes 2 fonctions de conversion, adaptées à des entiers signés sur 16 bits (complément à deux):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    def int2chrs(nb):
        if nb<0:
            nb = 65536+nb
        return chr(nb%256)+chr(nb//256)
     
    def chr2ints(ch):
        nb=ord(ch[0])+ord(ch[1])*256
        if nb>32767:
            nb=nb-65536
        return nb
    Le principe est simple: pour des valeurs négatives sur 16 bits (en complément à 2), le nombre négatif "n" a la même représentation binaire que le nombre positif 65536-abs(n). Cela permet à un mot de 16 bits de porter des valeurs de -32768 à +32767. C'est généralisable à un mot de longueur quelconque: pour 12 bits, c'est (1<<12)-abs(n).

    Si tu cherches des fonctions de conversion en chaînes binaires signées, j'en ai fait quelques unes ici avec les explications: http://python.jpvweb.com/mesrecettes...ons_en_binaire

    Mais il est vrai que struct est une excellente solution.

    Il est aussi possible (je n'ai pas essayé) qu'on puisse utiliser le module array qui peut porter (entre autres) des entiers signés ou non sur 16 bits. Ce module semble avoir des fonctions de conversion en chaîne de caractères qui respectent le type de nombre déclaré.

    Tyrtamos
    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

  18. #18
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Désolé, je n'avais pas fait attention au type de données que tu voulais extraire...

    Sinon, j'ai une question d'ordre plus général : je comprends bien qu'on puisse encoder un entier non signé sur 2 octets. Mais de savoir là où on met le poids fort... pourquoi ça dépendrait de l'OS ?
    Je peux très bien faire deux scripts qui enregistrent des données dans un fichier (mode RB), et c'est moi qui déciderait où je mettrais le poids fort, non ?

    Si je vais plus loin... Si j'ai besoin d'enregistrer une série de données, je pourrais moi-même 'créer' un format d'enregistrement adapté à mes besoins, non ?
    Exemple : le premier octet décide du signe, le deuxième la valeur, et le troisième, pourquoi pas, correspondra à une lettre ?


    N'empêche, j'aurais aussi appris plein de trucs aussi dans ce post...


    ##
    Christophe

  19. #19
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Le fait que l'octet de poids fort se trouve en 1er ou en dernier ne dépend pas de l'OS mais du processeur (architecture matérielle).

    Voir ici: http://fr.wikipedia.org/wiki/Petit-boutiste

    Par exemple, sur les PC (x86), le poids faible est en tête. C'est le contraire pour le SPARC de sun.

    Tyrtamos
    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

  20. #20
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Mai 2008
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Houlà, il va falloir que je potasse ça... à une heure moins avancée, et avec plus de neurones en activités...

    En tout cas, merci pour l'info.


    ##
    Christophe

    PS : je viens juste d'installer ta Calculext... elle est géniale !

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. ouvrir un fichier en mode binaire ?
    Par rimas2009 dans le forum Général Java
    Réponses: 1
    Dernier message: 19/05/2009, 11h57
  2. [Linux] Ouvrir un fichier en mode append
    Par nelob dans le forum Assembleur
    Réponses: 1
    Dernier message: 06/04/2007, 17h13
  3. Ouvrir un fichier en mode lecture
    Par marwa_rades dans le forum Assembleur
    Réponses: 1
    Dernier message: 29/12/2006, 14h51
  4. ouverture/lecture/ecriture dans un fichier en mode binaire
    Par dirty_boy dans le forum Débuter
    Réponses: 2
    Dernier message: 15/03/2006, 08h38
  5. Réponses: 4
    Dernier message: 04/11/2005, 09h04

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