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

Langage Perl Discussion :

iso14443b crc code conversion in perl


Sujet :

Langage Perl

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    technicien qualite
    Inscrit en
    Mars 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre (Centre)

    Informations professionnelles :
    Activité : technicien qualite

    Informations forums :
    Inscription : Mars 2018
    Messages : 3
    Points : 1
    Points
    1
    Par défaut iso14443b crc code conversion in perl
    Bonjour tout le monde !

    Jaimerais analyser un tag NFC iso14443b et comprendre comment cela fonctionne mais j’ai quelques soucis avec les CRC

    Quand le tag est lu on peut voir certains CRC, mais si je veux modifier le contenu des données je dois etre capable de créer un checksum correspond aussi .. et la je bloque.. voici quelques exemples:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #db# Address=00, Contents=dbce0cd3, CRC=2cbc
    #db# Address=01, Contents=cc2b2edb, CRC=681c
    #db# Address=02, Contents=ffffffff, CRC=470f
    #db# Address=03, Contents=ffffffff, CRC=470f
    j’ai trouvé le code source de la norme iso14443b pour calculer ce checksum mais en C ... or je suis pas très doué avec ce langage. Je sais comprendre les grandes lignes mais je n’arrive pas a transposer ce code en Perl correctement .. tous mes essais ont été infructueux.
    Code c : 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
    void
    iso14443b_crc(uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc)
    {
      uint32_t wCrc = 0xFFFF;
     
      do {
        uint8_t  bt;
        bt = *pbtData++;
        bt = (bt ^ (uint8_t)(wCrc & 0x00FF));
        bt = (bt ^ (bt << 4));
        wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
      } while (--szLen);
      wCrc = ~wCrc;
      *pbtCrc++ = (uint8_t)(wCrc & 0xFF);
      *pbtCrc = (uint8_t)((wCrc >> 8) & 0xFF);
    }
     
    /**
     * @brief Append CRC_B
     *
     */
    void
    iso14443b_crc_append(uint8_t *pbtData, size_t szLen)
    {
      iso14443b_crc(pbtData, szLen, pbtData + szLen);
    }

    Est ce que quelqu’un pourrait m’aider a le retranscrire en Perl svp ? avec des comments dans le code si possible ? =)

    Thanks =)

  2. #2
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 298
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 298
    Points : 12 778
    Points
    12 778
    Par défaut
    Bonjour,

    Le programme en C, ne ramène pas les checksum que tu donnes, à part pour 'ffffffff'...

    Sinon un exemple rapide en perl qui donne la même chose que le C (ici, j'ai pris comme exemple le calcul du checksum de dbce0cd3:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $wCrc = 0x0000FFFF;
    foreach my $i (0xDB,0xCE,0x0C,0xD3){
            $bt=$i;
            $bt=($bt ^ (0xFF & ($wCrc & 0x00FF)));
            $bt=($bt ^ (0xFF & ($bt << 4)));
            $wCrc = 0xFFFFFFFF & (($wCrc >> 8) ^  ($bt << 8) ^ ($bt << 3) ^ ($bt >> 4));
    }
    printf("%02X%02X\n",($wCrc ^ 0xFFFFFFFF)&0xFF,0xFF&($wCrc ^ 0xFFFFFFFF)>>8)
    Une version modifié du C, pour calculer le checksum de la même donnée:
    Code c : 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
    #include <stdint.h>
    int main(){
            uint32_t wCrc = 0xFFFF;
            uint8_t  bt;
            bt=0xdb;
            bt = (bt ^ (uint8_t)(wCrc & 0x00FF));
            bt = (bt ^ (bt << 4));
            wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
            bt=0xce;
            bt = (bt ^ (uint8_t)(wCrc & 0x00FF));
            bt = (bt ^ (bt << 4));
            wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
            bt=0x0c;
            bt = (bt ^ (uint8_t)(wCrc & 0x00FF));
            bt = (bt ^ (bt << 4));
            wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
            bt=0xd3;
            bt = (bt ^ (uint8_t)(wCrc & 0x00FF));
            bt = (bt ^ (bt << 4));
            wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
            wCrc = ~wCrc;
            printf("%02x",(uint8_t)(wCrc & 0xFF));
            printf("%02x",(uint8_t)(((wCrc >> 8) & 0xFF)));
    }
    Je garde explicitement le même calcul et les 2 code me ramène le même checksum.
    Après le problème est peut-être sur le paramètre szLen, qui ici j'ai supposé qu'il faisait la taille des données dont on veut faire le checksum ce qui est peut-être faux (comme on a pas l'information...)
    Cordialement.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    technicien qualite
    Inscrit en
    Mars 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre (Centre)

    Informations professionnelles :
    Activité : technicien qualite

    Informations forums :
    Inscription : Mars 2018
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Salut disedorgue !

    Merci d'avoir pris le temps de te pencher sur mon p'tit code ! et non il s'avère que ton code est tout à fait exact ! par contre les CRC que j'ai posté sont erronés mis à part pour les contents en " ffffffff ".

    j'ai été cherché la norme ISO/IEC 14443-3 sur le net et à la page 41 on y trouve le code pour le calcul et cela confirme bien les résultats de ton code aussi

    ( Je ne sais pas si j'ai le droit de mettre le lien du pdf ici donc par sécurité je m'abstiens, mais je peux le fournir en privé si tu veux. )

    Néanmoins dans ton code j'ai 1 petite question qui me taraude ... peux tu m'expliquer l'utilisation de ces opérations ( en rouge ) dans le code stp ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $wCrc = 0x0000FFFF;
    foreach my $i (0xcc,0x2b,0x2e,0xdb){
            $bt=$i;
            $bt=($bt ^ (0xFF & ($wCrc & 0x00FF)));
            $bt=($bt ^ (0xFF & ($bt << 4)));
            $wCrc = 0xFFFFFFFF & (($wCrc >> 8) ^  ($bt << 8) ^ ($bt << 3) ^ ($bt >> 4));
    }
    printf("%02X%02X\n",($wCrc ^ 0xFFFFFFFF)&0xFF,0xFF&($wCrc ^ 0xFFFFFFFF)>>8)
    Merci de ton aide en tout cas !!

  4. #4
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 298
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 298
    Points : 12 778
    Points
    12 778
    Par défaut
    Non, pas la peine pour le doc, je n'ai fait que transposer le code C en perl.

    Coté C, on a uint8_t et uint32_t, donc des entiers non signés de 8 ou 32 bits.

    Donc en perl, pour respecter ces tailles, je masque le surplus possible pour le 8 bits en ff et le 32 bits en ffffffff via un ET logique.

    Par contre, dans le print, le ou exclusif avec ffffffff c'est pour obtenir le complément logique de la valeur qui est représentée en C par wCrc = ~wCrc;.

    Le code doit être simplifiable, car ici on ne fait que des opérations de décalage ou de logique et dans ce cas, les seules règles à respecter sont:
    -on doit réduire avant un décalage à droite ( (X & FF) >> n pour un 8 bits ou (X & FFFFFFFF) >> n pour un 32 bits) dans tous les autres cas de décalage ou opérations logique, on peut réduire à la fin.
    Cordialement.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    technicien qualite
    Inscrit en
    Mars 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre (Centre)

    Informations professionnelles :
    Activité : technicien qualite

    Informations forums :
    Inscription : Mars 2018
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Ok je comprends mieux tout cela ! je ne faisais pas ce ET logique et OU exclusif ... d'ailleurs il faudrait je travaille un peu ce genre d'opérations car je n'y suis habitué du tout.

    J'avais bien compris qu'il fallait adapter les tailles pour correspondre au uint_8 et uint32_t mais, la façon de le faire n'était pas évidente pour moi.

    Merci pour ces réponses claires et précises !

Discussions similaires

  1. code conversion hexa\dec
    Par C_sharp dans le forum C#
    Réponses: 6
    Dernier message: 10/08/2009, 09h57
  2. Conversion timestamp perl vers timestamp Oracle
    Par danathane dans le forum SGBD
    Réponses: 3
    Dernier message: 26/01/2009, 16h45
  3. je comprend pas un code du cours perl
    Par fifto dans le forum Langage
    Réponses: 1
    Dernier message: 15/05/2007, 20h14
  4. [langage] code ascii en Perl
    Par intox18 dans le forum Langage
    Réponses: 3
    Dernier message: 18/01/2005, 09h35

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