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 :

[Problème ASCII] Hexadecimal to ASCII


Sujet :

Python

  1. #1
    Membre régulier
    Homme Profil pro
    Stagiaire
    Inscrit en
    Avril 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Stagiaire

    Informations forums :
    Inscription : Avril 2016
    Messages : 9
    Par défaut [Problème ASCII] Hexadecimal to ASCII
    Bonjour à tous,

    J'essaye en ce moment de développer un programme Python 2.7 dans le but de faire communiquer un raspberry PI et une voiture via le port OBD-II. Pour ce faire j'utiliser l'ELM 327 qui me permet de communiquer avec la voiture. Mon raspberry est connecté à l'ELM 327 en bluetooth, et peut envoyer des requêtes et reçois des informations de la voiture.

    Mon problème est le suivant : Les messages renvoyées par la voiture sont d'un certains format, et lorsque je veux connaître le VIN (Vehicle Identification Number) de la voiture, le message renvoyées est de la forme suivante :
    "014
    0: 49 02 01 xx xx xx xx
    1: xx xx xx xx xx xx xx
    2: xx xx xx xx xx xx xx"

    Dans le message suivant, le 014 indique le nombre de message qui nous intéresse en hexadécimal, ici 17 (nombre de caractères du VIN).
    Ensuite les 0: , 1: et 2: indique l'ordre dans lequel les informations sont envoyées et enfin, le 49 02 01 indique que le message qui suit est la réponse au message 09 02, celui qui donne le VIN.
    L'information à décoder sont donc les xx. Ces derniers sont en hexadécimal et il me faut donc les traiter afin de décoder le message en ASCII.
    Pour ce faire, la méthode que j'ai utiliser à été de traiter toutes les informations qui ne m’intéresse pas en utilisant la fonction .replace(). En enfin, ma variable code contient le message ci-dessus. J'effectue donc par exemple "code = code.replace("49 02 01", "")" pour supprimer de ma variable code le 49 02 01. J'effectue également pour le 014 ainsi que les "0:", "1:" et "2:". J'obtient donc une variable code de la forme suivante :
    "526621
    143DE4A263A31
    1343525255834"
    (j'ai volontairement changé les caractères pour ne pas mettre le VIN ne mon véhicule sur internet). Pour décoder ce message en ASCII, j'utilise la fonction :
    "vin = bytearray.fromhex(code).decode()".
    Le problème est que lorsque j'utilise cette fonction, j'obtient une erreur au changement de ligne (au 6 ème caractère de la première ligne). J'imagine que j'en obtiendrai une également au second changement de ligne mais le traitement du code ne va pas jusque là. L'erreur exacte est la suivante :
    "ValueError : non-hexadecimal number found in fromhex() arg at position 6".

    Je n'ai aucune idée de comment transformer ces valeurs hexadécimale en ASCII.
    Toute aide ou indication serait fortement appréciée. Merci d'avance à tous.
    Khoneb

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Salut,

    Citation Envoyé par khoneb Voir le message
    Le problème est que lorsque j'utilise cette fonction, j'obtient une erreur au changement de ligne (au 6 ème caractère de la première ligne). J'imagine que j'en obtiendrai une également au second changement de ligne mais le traitement du code ne va pas jusque là. L'erreur exacte est la suivante : "ValueError : non-hexadecimal number found in fromhex() arg at position 6".
    Le changement de ligne ('\n') n'est pas un digit hexadecimal.
    Vous pourriez "supprimer" ces changements de lignes mais les 17 octets d'un "vehicle identifiation number" doivent être interprétés de façon segmentée (voir leur format dans l'article wikipedia).
    Inutile d'essayer de faire marcher un "bytearray.fromhex(code).decode()": il n'y a aucune raison pour que çà fonctionne.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre régulier
    Homme Profil pro
    Stagiaire
    Inscrit en
    Avril 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Stagiaire

    Informations forums :
    Inscription : Avril 2016
    Messages : 9
    Par défaut
    Donc il me faut soit supprimer le changement de ligne '\n', soit utiliser une autre fonction pour décoder de l'hexadécimal en ASCII ?
    Je me suis renseigné un peu sur binascii, est-ce que cette bibliothèque à plus de change de fonctionner ?

    Merci d'avance.

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Salut,

    Citation Envoyé par khoneb Voir le message
    Donc il me faut soit supprimer le changement de ligne '\n', soit utiliser une autre fonction pour décoder de l'hexadécimal en ASCII ?
    Je me suis renseigné un peu sur binascii, est-ce que cette bibliothèque à plus de change de fonctionner ?
    non: il faut découper vos 17 octets en tranches/champs et les interpréter comme indiqué dans l'article.
    Comme il n'y a aucune raison pour que ces entiers soit dans 0..127, impossible d'en faire des caractères ASCII et çà vous servirait à quoi?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre régulier
    Homme Profil pro
    Stagiaire
    Inscrit en
    Avril 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Stagiaire

    Informations forums :
    Inscription : Avril 2016
    Messages : 9
    Par défaut
    Tout d'abord merci pour les réponses !

    Malheureusement je ne vois pas comment découper les octets comme l'article le montre. Je ne veux pas pouvoir en déduire les informations tels que marque du véhicule que contient le VIN mais juste obtenir le VIN exacte dans une chaîne de caractère. L'utilisation serait juste de rentrer les informations du véhicule dans une base de données.

    "Comme il n'y a aucune raison pour que ces entiers soit dans 0..127", que voulez vous dire par là ? Je suis désolé mais je suis débutant en Python et en décodage d'informations.

    Merci d'avance

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Salut,

    Citation Envoyé par khoneb Voir le message
    Malheureusement je ne vois pas comment découper les octets comme l'article le montre. Je ne veux pas pouvoir en déduire les informations tels que marque du véhicule que contient le VIN mais juste obtenir le VIN exacte dans une chaîne de caractère. L'utilisation serait juste de rentrer les informations du véhicule dans une base de données.
    Le contenu de la variable "code" que vous avez est déjà le VIN sous la forme d'une chaîne de caractère ASCII.

    Citation Envoyé par khoneb Voir le message
    "Comme il n'y a aucune raison pour que ces entiers soit dans 0..127", que voulez vous dire par là ? Je suis désolé mais je suis débutant en Python et en décodage d'informations.
    Je comprends que vous ne compreniez pas mais vous avez plein de tutos, cours, bouquins, ... avec lesquels vous pouvez apprendre les bases. Tapez ASCII sur Google, vous allez avoir un article Wikipedia qui va vous expliquer ce que c'est. Cà date des années 60 depuis nous avons inventé des tas d'autres notions/concepts qu'il faut connaître pour programmer en comprenant un peu ce qu'on fait.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre régulier
    Homme Profil pro
    Stagiaire
    Inscrit en
    Avril 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Stagiaire

    Informations forums :
    Inscription : Avril 2016
    Messages : 9
    Par défaut
    J'irais alors me documenter là dessus, mais en revanche pour ce qui est de :
    Citation Envoyé par wiztricks Voir le message
    Salut,

    Le contenu de la variable "code" que vous avez est déjà le VIN sous la forme d'une chaîne de caractère ASCII.


    - W
    Le contenu de la variable "code" est en hexadecimal. Si dans ma variable code j'ai "31", cela veut dire qu'il y a un "1" dans mon VIN. Je cherche justement à faire cette transition, je ne vois donc pas en quoi le contenu de code est sous la forme d'une chaîne de caractère ASCII.

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Citation Envoyé par khoneb Voir le message
    Le contenu de la variable "code" est en hexadecimal. Si dans ma variable code j'ai "31", cela veut dire qu'il y a un "1" dans mon VIN.
    Un octet est représentable par un nombre dans 0..255 sous forme hexadecimale.
    "31" est la représentation hexadécimale du nombre 49.
    "1" sera la représentation de ce nombre là en caractère ASCII.
    Ceci dit, si une chaine de caractère ASCII pourra être représentée sous forme hexadécimale, la réciproque n'est pas vraie puisqu'on ne sait pas représenter en ASCII les nombres dans 128..255. Votre idée pourrait fonctionner si le VIN était une chaine de caractères ASCII (représentée sous forme hexa), mais comme n'est pas le cas (voir article), elle ne marche pas.

    Citation Envoyé par khoneb Voir le message
    Je cherche justement à faire cette transition, je ne vois donc pas en quoi le contenu de code est sous la forme d'une chaîne de caractère ASCII.
    Le problème quand on débute est qu'on a du mal à comprendre ce qu'il se passe devant ses yeux.
    Imaginez la suite de nombre (décimaux): 49, 50, 51, 52
    Si vous les voyez, c'est parce que je les montre sous forme de caractères (ASCII).
    J'aurais pu les écrire sous forme hexa: 31, 32, 33, 34
    Vous voyez une autre représentation de ces mêmes nombres.
    Si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> bytearray.fromhex(b'31323334').decode()
    u'1234'
    çà marche parce qu'on applique bytearray.fromhex à une chaine de caractères de "digits" hexadécimaux qui ont le bon goût d'être dans 0..127 ou '00'..'7f'.
    Si on essaie de le faire pour:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> bytearray.fromhex(b'3132333481').decode()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0x81 in position 4: ordinal
    not in range(128)
    >>>
    çà plante... normal à cause du 81.
    Mais vous pourriez écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> b'3132333481'.decode()
    u'3132333481'
    >>>
    parce qu'une chaine de caractères de digits hexa est nécessairement ASCII.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre chevronné
    Homme Profil pro
    Développeur banc de test
    Inscrit en
    Mai 2014
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur banc de test
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2014
    Messages : 199
    Par défaut
    Bonsoir,

    je ne suis pas sûr de bien comprendre le besoin.

    Pour bien comprendre :

    Votre entrée est de type string/str, son encodage est en ASCII.
    Première étape on peux déjà le décoder pour passer en unicode et ainsi vérifier qu'on respecte le range(128) de la table ASCII de chaque octet.

    u_message = "1FF".decode("ascii")

    Seconde étape, si je comprend bien, pour avoir déjà vu des protocoles faire de même, c'est à dire transporter tout le contenu en ASCII, les nombres et autres, mais transcrits non pas en décimal mais en hexadécimal, sans les '0x'

    Et si c'est bien le cas, alors il suffit comme en décimal d'utiliser la fonction int(), mais de changer la base par défaut qui est à 10 par 16:

    valeur = int(u_message, base=16)

    et là on obtient 511, soit 0x1ff en hexadécimal.

  10. #10
    Membre régulier
    Homme Profil pro
    Stagiaire
    Inscrit en
    Avril 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Stagiaire

    Informations forums :
    Inscription : Avril 2016
    Messages : 9
    Par défaut
    Bonjour à tous et merci pour vos réponses.

    Je pense savoir d'où viens l’incompréhension : Ce que me renvoie le port OBD-II n'est pas exactement le suivant, je l'ai modifié volontairement pour ne pas l'afficher sur le web et j'ai en effet dû mettre des chiffres qui dépasse le 128 en hexadécimal (66 par exemple).
    "526621
    143DE4A263A31
    1343525255834"
    Mais le code que me renvois ma voiture est au bon format et ne dépasse pas les dites bornes. Le problème que je reçois lorsque je compile monde code viens du retour à la ligne et non pas des valeurs propre du message. Si je traduit "à la main" ce dernier en ASCII j'obtient bien le bon VIN qui est inscrit sur le châssis de ma voiture.
    Je pense que c'est ça que vous vouliez me dire, mais je pense que le problème que vous avez vu est simplement celui que j'ai créer sans faire exprès pour "cacher" le VIN de mon véhicule.

    Cordialement,
    Khoneb

Discussions similaires

  1. Petit problème pour écrire en ASCII sur spritebatch
    Par skuller42 dans le forum XNA/Monogame
    Réponses: 1
    Dernier message: 24/02/2015, 14h50
  2. [Python 2.X] Problème affichage caractères non ASCII
    Par nekcorp dans le forum Général Python
    Réponses: 10
    Dernier message: 26/01/2015, 11h49
  3. Problème avec un tableau ascii
    Par Stephane_br dans le forum VB.NET
    Réponses: 0
    Dernier message: 11/02/2014, 13h45
  4. Petit problème de conversion EBCDIC -> ASCII
    Par alex140025 dans le forum Langage
    Réponses: 4
    Dernier message: 29/07/2011, 11h08
  5. texte --> ascii hexadecimal
    Par oeil de lynx dans le forum Débuter
    Réponses: 8
    Dernier message: 02/04/2008, 23h42

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